Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

All staged, but uncommitted, files deleted after issuing: git reset --hard HEAD

Normally, you can do:

$ echo "Stanley, you must beware of the Drive bee" > file-a
$ echo "What's a Drive bee?" > file-b
$ git init .
$ git add file-b
$ git commit file-b -m "We don't know, but whatever error you make with it could be fatal."
$ git reset --hard HEAD
$ ls
file-a file-b

I think I did something really bad:

$ echo "What are you doing, you darn 🐝?" > file-a
$ echo "Can't you see I'm trying to drive?" > file-🐝
$ git init .
$ git add -A
$ git commit file-🐝 -m "Oh, my God! [It's] the Drive 🐝!"
$ git reset --hard HEAD
$ ls
file-🐝

Result: all staged, but uncommitted, files deleted 0_o

git reset --hard HEAD\^
fatal: ambiguous argument 'HEAD^': unknown revision or path not in the working tree.

Is there anything I can do to recover the file I just deleted? In other words, is it possible to restore a git repository to the condition it was before (or when) the git add -A command was issued?

like image 330
dcow Avatar asked Jul 23 '12 22:07

dcow


2 Answers

Yes, you are actually really lucky. What you added to Git’s index is there, in some way. In fact, Git does create blob objects for each file already when it is added to the index. The index itself only stores the tree objects.

So yes, there were blob objects created for your staged files. All you lose are the tree information, i.e. path and filename, but you can recover the content.

Try running git fsck and you should get a list of dangling blobs:

Checking object directories: 100% (256/256), done.
dangling blob ac28af8d84fc71eb247ccf665c6d0f4bf1822520
dangling blob 2d152ff9f09cb08ebc495f453da63eddaa9e249f
dangling blob cd9567427762cd8066b4e802e5c170a31a026100

You can then recover the contents by doing git cat-file -p ac28af8d. For example you can pipe that to a file:

git cat-file -p ac28af8d > recovered-file

Do that for all of them and you have them back.

like image 148
poke Avatar answered Sep 28 '22 04:09

poke


The following script restore all dangling blobs from git fsck output into files:

i=0; for x in `git fsck | grep "dangling blob [0-9a-f]" | cut -d ' ' -f 3`; do git cat-file -p $x > /tmp/test${i}; i=$((i+1)) ; done

As you can see, the output of each original file is restored into generic filename /tmp/test${i} ... I haven't found a way to restore the file name yet... the command I've tried is git ls-tree:

First I've took possible objects :

./.git/objects/37
./.git/objects/37/5187f5882593f7e52c8efef602d98f1f049c5d
./.git/objects/37/98be05fcbd7c79e08703aead800529b362332b

Then, I tried to do the ls-tree trick, but it failed to identify this as a valid object.

/<myproj>/.git/objects/37 ]$ git ls-tree 5187f5882593f7e52c8efef602d98f1f049c5d 
fatal: Not a valid object name 5187f5882593f7e52c8efef602d98f1f049c5d
like image 23
Zohar81 Avatar answered Sep 28 '22 06:09

Zohar81