When I check out a file with git checkout $commit $filename
and I forget $commit
but still remember $filename
, how do I find out what $commit
was?
-
1http://stackoverflow.com/questions/223678/git-which-commit-has-this-blob – Josh Lee Aug 05 '11 at 14:10
-
@jleedev I would accept that as an Answer if I could ^^ – j-pb Aug 05 '11 at 14:20
-
2Voting to close as a duplicate of jleedev's link. Just wanted to add that you use `git hash-object filename` to get the hash needed in that answer. – Karl Bielefeldt Aug 05 '11 at 15:32
7 Answers
First a non-git answer. Check your shell command history. Well, if you didn't use a shell with command history then you don't...
The git answer. You generally cannot find THE $commit. Generally the same contents might have been part of many commits and I don't think git keeps a log of what single file you have checked out (it keeps a log of previous values of HEAD)
Here is a brute force script git-find-by-contents. Call it with your $filename as parameter, and it will show you all commits where this file was included. As the name says it searches by contents. So it will find files with any name, as long as the contents matches.
#! /bin/sh
tmpdir=/tmp/$(basename $0)
mkdir $tmpdir 2>/dev/null
rm $tmpdir/* 2>/dev/null
hash=$(git hash-object $1)
echo "finding $hash"
allrevs=$(git rev-list --all)
# well, nearly all revs, we could still check the log if we have
# dangling commits and we could include the index to be perfect...
for rev in $allrevs
do
git ls-tree --full-tree -r $rev >$tmpdir/$rev
done
cd $tmpdir
grep $hash *
rm -r $tmpdir
I would not be surprised if there is a more elegant way, but this has worked for me a couple of times in similar situations.
EDIT: a more techy version of the same problem appears here: Which commit has this blob?

- 1
- 1

- 2,236
- 1
- 15
- 21
I don't think you can. Git just loads that version of the file into the index and your working dir. There is no reference keeping track of what version it loaded
If this is something that you do often, you could write up a script that could do it using git diff --cached
and march through all the commits that changed that file.

- 44,610
- 13
- 70
- 69
You can use
git log <filename>
to find out which commit you want to checkout

- 25,806
- 45
- 116
- 158
-
Nope, the log will start with the commit history of HEAD. And I don't want to search through the log history until I find something familiar, but rather automated. – j-pb Aug 05 '11 at 14:06
If you're lucky, you could maybe try a non-git way:
history | grep "git checkout.*filename"

- 64,417
- 29
- 168
- 201
Try this (untested ;):
$ for commit in $(git log --format=%h $filename); do
> if diff <(git show $commit:$filename) $filename >/dev/null; then
> echo $commit
> fi
> done

- 15,653
- 1
- 40
- 50
Simple and elegant:
$ git log -S"$(cat /path/to/file)"
Only works if the content is unique, then again that's the same for the hash-comparison answers that came before.
It also displays only the first version that matches, rather than all.

- 9,495
- 6
- 30
- 27
Here are the details of a script I polished up as the answer to a similar question, and here you can see it in action:
(source: adamspiers.org)

- 21,988
- 13
- 81
- 109

- 17,397
- 5
- 46
- 65