Frage

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?

War es hilfreich?

Lösung

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?

Andere Tipps

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.

You can use

git log <filename>

to find out which commit you want to checkout

If you're lucky, you could maybe try a non-git way:

history | grep "git checkout.*filename"

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 

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.

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:

screenshot of git-ls-dir runs
(source: adamspiers.org)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top