git存储库的确定性校验和

时间:2017-05-16 19:00:35

标签: git

我想创建(裸)git存储库的校验和,因此两个等效的存储库将具有相同的校验和。有没有git-idiomatic方法呢?

  • tar + md5不会直接工作,因为在不同时间克隆的两个存储库会有不同的时间戳,而tar存储时间戳

  • 即使时间戳被规范化,对于从同一源克隆的两个存储库,git pack文件也可能不同(我不知道为什么它们不同,我猜测时间戳或文件顺序)。

2 个答案:

答案 0 :(得分:2)

听起来你想知道两个repos是否等同于而不是相同,为此你需要为什么是等价来制定规则

内部git可以代表相同的内容"要么是松散的对象,要么是打包的对象。回购可能有一个包装,多个包装,包装和松散物品的组合。我无法想到如果内容相同,两个包装文件会有所不同的原因,但我不想发誓他们不能......

另一方面,如果使用LFS而另一个不使用LFS(或者如果他们使用LFS跟踪不同的内容子集),您是否要考虑两个repos等效?它们可能仍然包含完全相同的版本(因为您通过签出工作树来查看它们),并且可以以相同的方式访问给定版本(只要该方式相对于ref) ......但能够将这些识别为"等同于"会使你的工作变得更加困难(并且运行资源更加密集)。因此,我假设您不必担心这一点,但重点是要强调:没有解决方案是真正的一般性。

嗯,足够的哲学:没有极端条件,你可以做到

git for-each-ref

查看每个分支,标记或其他命名入口点以及当前的sha1。如果两个ref(或ref的两个副本)具有相同的sha1值,则它们具有相同的历史。 (哈希冲突不是一个现实问题。)

您可以将其提供给git hash-object。我先排序(因为我是偏执狂),你可能想要排除远程参考(如果远程关系不重要),那么

git for-each-ref |grep -v refs\/remotes |sort |git hash-object --stdin

(你可能会改进我使用的grep模式,但对于一个应该运行良好的快速和脏的一个衬垫。)

答案 1 :(得分:0)

给定提交的SHA1校验和几乎完全相同。它唯一(在没有SHA1冲突的情况下)识别给定的提交,包括导致它的所有历史记录。但是,这并没有为具有多个独立分支的回购提供足够的信息。

像这样的伪代码可能是一个好的开始:

For each branch (output of "git branch"):
    Run "git log -n 1" on that branch and capture the SHA1
Print all the collected SHA1s in sorted order and compute a checksum of the result.

这不会捕获不在任何分支上的提交(包括标记的提交)。可能还有其他信息无法捕捉 - 尽管产生相同结果的两个回购不太可能产生任何真正的差异。

(请随意使用此作为更好答案的基础。)