在Git中查找文件的第一个提交

11

情境:我有一个来自Github项目的tar.gz版本发布包,但想要确定它是从哪个提交中获取的。它似乎没有被标记,也不明显从提交消息本身中看出。

因此,我可以计算文件的sha1,但想知道这些文件属于哪个提交?

呼叫Git高手!


2
为什么会有踩票?这是一个有趣的问题。他有一些文件,它们来自Git存储库,但目前不在版本控制下,他想知道它们对应哪个版本。这是一个合理的问题。 - eykanal
点赞。这是一个很棒的问题,揭示了Git存储历史记录的出色方式。 - Adam Dymitruk
感谢两位出色的回答。我在提问时假定tar.gz是存储库的精确导出 - 但是尝试了两种方法后,似乎只有一个非常接近的提交,区别在于README文件,这些文件似乎已经被手动编辑以进行发布。因此,将信用归给基于差异的答案,但这并不意味着另一个答案不是同样出色的答案。再次感谢。 - bee
2个回答

2

由于文件属性可能会变得棘手,因此这种方法可能有些麻烦。假设它们没有改变或者你查看了仓库存储的内容,请确保它们是相同的。将其提交到仓库中,然后查看树的哈希值。

git show -s --pretty=format:%T HEAD

现在遍历版本库中的所有提交记录,查看是否有任何一个提交记录有与之相同哈希值的树。
git log --all --format=%H

这将为您提供所有提交哈希值。现在将其导入以显示树哈希值。

git log --all --format=%H \
  | xargs -n 1 git show -s --pretty='format:%H %T' \
  | gerp <hash of your tree>

如果tar文件包含完全相同的结构和权限,输出将显示具有相同树的提交的SHA1值。

搜索顶层树的SHA1将非常快速。


2

由于Git存储的哈希值不仅包括文件内容(理论上,哈希冲突仍然会发生),为了确保您拥有正确的文件版本,您需要比较内容。

for rev in $(git log --format=%H -- /path/to/file); do
   git diff --quiet $x:/path/to/file my-current-file;
   if [[ $? -eq 0 ]]; then
      echo $x;
   fi
done

在英语中:按照相反的顺序迭代更改文件的修订版。对于每个这样的修订版,将该处文件的版本与树外文件进行比较。如果两个文件相同,打印修订版的哈希值。
如果您想对整个tarball执行此操作,可以做相同的操作,但是将整个树与单个文件进行比较(并且省略将文件路径作为参数传递给git log)-使用任何您喜欢的宽容的diff选项。

你需要匹配tar文件中的所有文件,以找出tar文件的来源。 - Adam Dymitruk
@AdamDymitruk,我在答案末尾添加了一条注释。 - Borealid
在这种情况下,可能需要很长时间才能找到。但是,您确实消除了文件属性的歧义。 - Adam Dymitruk
宽容的差异选项会给你错误的结果。你需要精确匹配。 - Adam Dymitruk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接