当我签出一个文件时git checkout $commit $filename
,我忘记了$commit
,但仍然记得$filename
,我如何找出是什么$commit
?
7 回答
首先是一个非 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
如果有更优雅的方式,我不会感到惊讶,但这在类似情况下对我有用几次。
编辑:这里出现了同样问题的一个更技术化的版本:哪个提交有这个 blob?
我不认为你可以。Git 只是将该版本的文件加载到索引和您的工作目录中。没有参考跟踪它加载的版本
如果这是您经常做的事情,您可以编写一个脚本来执行此操作git diff --cached
,并遍历更改该文件的所有提交。
您可以使用
git log <filename>
找出您要签出的提交
如果你幸运的话,你也许可以尝试一种非 git 方式:
history | grep "git checkout.*filename"
试试这个(未经测试;):
$ for commit in $(git log --format=%h $filename); do
> if diff <(git show $commit:$filename) $filename >/dev/null; then
> echo $commit
> fi
> done
简单优雅:
$ git log -S"$(cat /path/to/file)"
仅在内容是唯一的情况下才有效,然后对于之前出现的哈希比较答案也是如此。
它还仅显示匹配的第一个版本,而不是全部。
以下是我完善的脚本的详细信息,作为类似问题的答案,您可以在这里看到它的实际效果:
(来源:adamspiers.org)