我有任意文件foo
,没有提交给 git。
我还有一个文件,其整个历史记录都保存在 git 中,bar
.
我如何确定是否与曾经存在foo
的任何版本相同?bar
很容易判断文件的内容是否foo
出现在 repo 的某处:
file=foo # or argument to script, etc
sha1=$(git hash-object -t blob $file)
repotype=$(git cat-file -t $sha1 2>/dev/null) || {
echo "file \"$file\" is not in the repo"
exit 1
}
[ $repotype = blob ] || {
echo "uh oh: file \"$file\" matches non-file ($repotype) object"
exit 1
}
但是,仅仅因为foo
作为 blob 出现在 repo 中,并不意味着它出现在名称下bar
(或者甚至可能根本没有,它可能已经被git add
编辑但从未在提交下签入)。因此,现在查看每个(合理的?)提交,为您的目标路径提取 blob-ID,如果不存在则跳过提交:
target_path=bar
git rev-list --branches | # or --all, or HEAD, or (etc)
while read id; do
file_id=$(git rev-parse -q --verify $id:$target_path) || continue
[ $file_id = $sha1 ] || continue
echo "found \"$file\" as \"$target_path\" in $id"
# do more here if you like, e.g., git show $id
done
如果您想以任何名称而不是某个特定的显式名称来查找它,您可以git ls-tree -r
每次提交以查找所有blob
s 并检查它们的 ID。
(注意:除了零碎之外未经测试,并且偶尔可能会在此过程中重新输入或更改,请注意拼写错误或愚蠢的错误)
使用md5sum
,git log
和的组合grep
将起作用:
for SHA in `git log --pretty=format:"%h" bar`; do
git show $SHA:bar | md5sum
done | grep `md5sum foo| cut -d' ' -f1`
上面的命令git log --pretty=format:"%h" bar
获取bar
文件的所有提交列表,然后我们对每个提交执行 md5sum (git show
以显示该提交中的文件)。foo
最后我们grep文件的md5sum