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?
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With