2

This is the situation: I've lost some work in my git repository, this work was once commited, but is now burried in my history, somewhere that might be unreachable by 'git log --all'. The only thing I've can remember is some distinct string that could pinpoint a file that is part of my work at this time.

I've got a solution... but it is quite long, have you a better solution ?

This is my solution:

I've managed to find my commit SHA1 by batching several command:

  • first finding all 'blob' objects in the .git/objects, 'git cat'ing them (and using grep) to find the SHA1 of the blob that contained my file.
  • Then I had to parse all 'tree' objects to find which contained the SHA1 of the file... up to the tree object that was contained in no other 'tree' objects.
  • To finally parse all commit that contained this root tree.
vaab
  • 9,685
  • 7
  • 55
  • 60

1 Answers1

7

If the commit is reachable from some ref, the optimal solution would pretty definitely be the pickaxe search: git log -Sstring --all.

If it's not reachable, you're right, you're going to have to do some digging. If you think you have dangling commits scattered all over the place, the easiest thing to do would be to use git fsck --lost-found to find your dangling commits. (It'll also print dangling blobs.) You can then use git grep <commit> on each of these SHA1s, and find your string.

On the other hand, if you think that you have a few candidate branches that got pruned, and your target will be on one of them, I would use git reflog show to look back into your reflogs, find the commits that were at the tips of them, and recreate them, so you can do git log -Sstring <branches> ^master.

Cascabel
  • 479,068
  • 72
  • 370
  • 318
  • I'm sorry, this doesn't answers my question: Your 3 alternatives are based on an information that was said to be unknown: "is the commit in a reachable branch or not ?". And you do not provide a simpler way, although I agree there might be none. – vaab Oct 07 '11 at 12:57
  • Even if you don't know if it's reachable, you should *always* try with `git log` first, since it will be much, much faster. And the second choice does *not* depend on being reachable from refs - in fact, it only lists commits which *aren't* reachable. It **is** the answer, and it's better than your method, because it avoids examining blobs which *are* reachable. The third one is a compromise, for when they aren't currently reachable, but you have an idea where to look, since fsck is time-consuming. – Cascabel Oct 07 '11 at 15:51