如何找出签出文件的提交内容

时间:2011-08-05 13:55:21

标签: cherry-pick pre-commit git-checkout

当我查看包含git checkout $commit $filename的文件并忘记$commit但仍记得$filename时,如何找出$commit是什么?

7 个答案:

答案 0 :(得分:2)

首先是一个非git的回答。检查shell命令历史记录。好吧,如果你没有使用带命令历史记录的shell,那么你就不要......

git的答案。您通常无法找到 THE $ commit。通常相同的内容可能是许多提交的一部分,我不认为git会记录您检出的单个文件(它记录了HEAD的先前值)

这是一个强力脚本git-find-by-contents。使用$ filename作为参数调用它,它将显示包含此文件的所有提交。顾名思义 它按内容搜索。因此,只要内容匹配,它就会找到任何名称的文件。

#! /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

如果有更优雅的方式,我不会感到惊讶,但在类似的情况下,这对我有用了几次。

编辑:此处出现了同一问题的更为技术性的版本:Which commit has this blob?

答案 1 :(得分:1)

我认为你不能。 Git只是将该版本的文件加载到索引和工作目录中。没有参考记录它加载的版本

如果您经常这样做,可以编写一个可以使用git diff --cached执行此操作的脚本,然后执行更改该文件的所有提交。

答案 2 :(得分:0)

您可以使用

git log <filename>

找出要结帐的提交

答案 3 :(得分:0)

如果你很幸运,你可以试试非git方式:

history | grep "git checkout.*filename"

答案 4 :(得分:0)

试试这个(未经测试;):

$ for commit in $(git log --format=%h $filename); do
>  if diff <(git show $commit:$filename) $filename >/dev/null; then
>    echo $commit
>  fi
> done 

答案 5 :(得分:0)

简单而优雅:

$ git log -S"$(cat /path/to/file)"

只有在内容是唯一的情况下才有效,然后对于以前的哈希比较答案再次相同。

它还只显示匹配的第一个版本,而不是全部。

答案 6 :(得分:0)