7

I am a git noob and git just deleted a bunch of important files. How do I get them back?

I have a repo on my local machine. To get into git, I just right click my project folder and select "git bash here". This brings up the master where I do all my giting.

So I had some changes to stage and I did:

git add .

This staged a bunch of changes. I noticed that I didn't want some of these staged so I decided that I'd try to unstage everthing. I did this:

git reset --hard HEAD^

This basically deleted a bunch of files that I had made on the last commit and jumped to the commit before.

How do I get those files back? If I can't do it through git is there another way?

Ryan
  • 5,883
  • 13
  • 56
  • 93
  • possible duplicate of http://stackoverflow.com/questions/1108853/recovering-added-file-after-doing-git-reset-hard-head – tanascius May 06 '10 at 10:47

6 Answers6

10

I stand corrected regarding my original advice (see edit history). As penance, I've tracked down the simplest way to recover your lost files from git:

git fsck --lost-found
ls .git/lost-found/other

Unfortunately, the filenames are lost, but the contents should all be there as distinct files.

Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • 1
    He used `git add .` ... so he should be able to recover – tanascius May 06 '10 at 11:03
  • does fsck affect my repo at all? because I already did a: git reset --hard {removed head} to get back some of the changes. but i still need to get back my uncommited changes – Ryan May 06 '10 at 15:17
  • If you're at all concerned, just backup the entire repo first using something other than git. But I don't think fsck will damage anything. – Marcelo Cantos May 06 '10 at 22:57
  • You have no idea how much time you just saved me from a bone-headed fat-fingered operation. Thank you! – Brandon Bloom Apr 05 '12 at 19:13
  • In some cases, `git` can even recover the filenames: http://stackoverflow.com/questions/1108853/recovering-added-file-after-doing-git-reset-hard-head/15472831#15472831 – Mikko Rantalainen Oct 01 '13 at 12:15
1

From this SO-Question:


You can (with some work) recover state of file at the last "git add <file>". You can use

$ git fsck --cached --no-reflogs --lost-found --unreachable HEAD

and then examine files in '.git/lost-found/blob/' directory.

Please read git fsck manpage: I have not checked above invocation.


Community
  • 1
  • 1
tanascius
  • 53,078
  • 22
  • 114
  • 136
1

It sounds like you want the old HEAD (as opposed to HEAD^), in which case you can simply check out that revision. Use git reflog to show the previous HEADs and look for the commit you want, then check it out.

If you want the files that you staged before the reset, see the other answers.

Brian Cully
  • 526
  • 2
  • 11
  • Good advice - of course the reflog will help to recover the last commit ... together with my fsck solution he should be able to restore all files. – tanascius May 06 '10 at 20:02
1

I know this is an old thread, but I have to add something here.
after using

$ git fsck --cache --no-reflogs --lost-found --unreachable HEAD

we get the list of thousands of files (like it was for me) and looks like it's no possible to check all ones manually so we can filter the list to find blob files only in any suitable way for you, in may case it was Python and I just copied the output of the git fsck from console to the file the read file to get a list of rows

with open("lost_files.txt") as file:
    lost_files = file.readlines()

Then filter to separate blob ones

[line.split(' ')[-1].strip() for line in lost_files if "blob" in line]

result was the list of hashes Then go to console and declare a variable FILES and past here the list of hashes generated above FILES=('5c2d8667ef8abbd7e114d2f9b61ee840b034e56f' ....... '6dad86cd9c7a80ff5c3cd1d3222d2f8228dc18cf') for it was near 5К files then just write a simple loop in console

for lost_file in "${FILES[@]}"; do   git show  $lost_file > lost/lost_file_$lost_file.txt; done

as result I get 5К files in lost directory Then it's need to simply open each file and grep data you want for me it was next script ( I try to use meaningful naming when working on features so I just add filter by keyword)

import os

lost_files_names = os.listdir("lost")
names = []
for file in lost_files_names:
    with open(f"lost/{file}", "rb") as data:
        temp = data.readlines()
    for x in temp:
        if b"my_keyword" in x:
            names.append(file)
for x in set(names):
    print(x)
 

Finlay I have got output with 10 files and managed to restore stupidly lost uncommitted code (Thank god, I did git add) in a short amount of time

  • "I just copied the output of the git fsck from console to the file" Are you familiar with output redirection? If not, take a look at it. It's a great tool to do this all in a single command instead using your mouse to highlight and copy the text and then pasting it into an editor. – Code-Apprentice Jul 29 '22 at 20:19
  • 1
    Thanks, not so familiar with this, but yes, you are right, I know it's possible to do the same with cmd command only, I chose the easiest way for me at that time)) – Max Pototskiy Jul 29 '22 at 20:39
0

No, with

git reset --hard HEAD^

the changes are reverted back to the last commit and lost permanently.

phoenix24
  • 2,072
  • 2
  • 20
  • 24
0

As @tanascius mentioned, you can use the below command to restore added, but not committed files. This command prints in console SHA-1 references to the blob and trees objects.

$ git fsck --cache --no-reflogs --lost-found --unreachable HEAD

The blob objects are exactly your files that were lost by git reset command. Use the following command to restore it (actual filenames are lost, unfortunately):

$ git show "<SHA-1 REFERENCE TO THE BLOB OBJECT HERE>" > lost_file.txt
Michael Abyzov
  • 452
  • 1
  • 6
  • 16