检查两个git存储库是否不相关的简单方法是什么?

时间:2018-11-11 10:44:25

标签: git

检查两个git存储库是否不相关的简单方法是什么?

例如,假设我们克隆了以下存储库:

如何检查一个人不与另一个人分享历史记录?

如何检查一个与另一个共享部分历史记录?如何浏览常见的DAG并查看差异?

注意:Git允许浅拷贝+存储库的历史记录可以随时间变化...

3 个答案:

答案 0 :(得分:3)

您可以克隆第一个,然后将第二个添加为其他遥控器:

git clone https://github.com/spring-petclinic/spring-framework-petclinic
cd spring-framework-petclinic
git remote add other https://github.com/spring-projects/spring-petclinic
git fetch --all

然后,您可以浏览两个DAG:

git log --graph --all --oneline --decorate

通过查看两个主干的合并基础,查看它们是否具有共同的历史记录:

git merge-base origin/master other/master

答案 1 :(得分:1)

很容易证明两个存储库 是相关的:如果它们包含匹配的提交,则使用相同的哈希ID和内容进行提交,尽管“相同的哈希ID”通常就足够了 1 -它们是相关的。

您注意到,要证明它们是 un 相关的要困难得多,除非它们都是完整的(非浅层,非单分支)克隆。如果两者均已完成,但又没有一个共同的提交,则这两个存储库是无关的。

如果您同时拥有两个存储库并验证两个存储库都完整,则只需枚举两个存储库中的所有提交哈希ID并查找通用ID。如果存在公共ID,则这两个可能是相关的。要枚举所有提交哈希ID,请运行git rev-list --all(将输出重定向到文件或读取两组输出并检查通用哈希ID的程序)。

请参阅脚注1,以消除“可能”,但TL; DR表示,任何两个相同的ID表示共享历史记录。


1 给出一个统一的哈希函数 h(k),其范围为 r == || {h(k)| ,两个不同键 k 1 的偶然哈希冲突, k 2 p = 1 r 。唯一性的可能性是其补充值p̄= 1 =(1 / r)。推广到 n 键,并对 x≪ 1 使用 e x ≈1 + x 的两项泰勒展开>,只要 r 相当大,我们就会得到p̄≈e(-n(n-1))/ 2r

Git的哈希函数当前为SHA1,具有相当均匀的分布,并且r = 2 160 =1461501637330902918203684832716283019655932542976。这满足我们的公式,这意味着我们可以使用近似值。

因此,如果您对哈希的总数 n 求和并将其插入公式:

r=1461501637330902918203684832716283019655932542976
1 - exp(-n*(n-1)/(2*r))

(请记住,我们要的是p,而不是p-bar), 您就有发生碰撞的可能性。当然,要检查实际碰撞,您可以只比较基础的实际对象:如果哈希匹配,则直接比较对象以检测碰撞。但这首先是极端。如果我们采用两个包含一千万次提交的存储库,则我们将计算:

$ bc -l
r=2^160
n=10*1000*1000
scale=100
1 - e(-n*(n-1)/(2*r))
.0000000000000000000000000000000000342113848680412753525884397196522\
895097282878872708411144841034243
如您所见,

仍然很小。直到我们到达:

n=10*1000*1000*1000*1000*1000*1000*1000

(十个六十亿个对象,使用短尺度表示法)

我们发现:

1 - e(-n*(n-1)/(2*r))
.0000342108030863093209851036344159518189002166758764416221121344549\
079733424124497666779807175655625

意外碰撞的机会很明显,大约为0.0035%。在100亿个物体上,我们有0.35%的机会:

n=100*1000*1000*1000*1000*1000*1000*1000
1 - e(-n*(n-1)/(2*r))
.0034152934013810288444649336362559390942558976421984312395097770719\
923433072593638116228277476790795

通过9亿个对象,我们面临着一些严重的风险:

1 - e(-n*(n-1)/(2*r))
.2897326871923714506502211457721853341644126909116947422293621066225\
555385326652788789421475224989232

幸运的是,在此之前,我们已经用完了磁盘空间。 :-)而且,Git家伙正在考虑转移到SHA-256哈希之一,这会将 r 提升到2 256 ,这有助于我们的分母。 / p>

(我在上面使用bc,其中^是幂运算,-l库添加了e(x)以计算 e x 。)

答案 2 :(得分:0)

要查找任何常见的修订版本,请执行以下操作:

comm -12 <(cd repo1; git rev-list --all | sort) <(cd repo2; git rev-list --all | sort)

在我的情况下,两个存储库共享提交:

bash# (cd spring-petclinic; git rev-list --all) | wc -l
670

bash# (cd spring-framework-petclinic; git rev-list --all) | wc -l
571

bash# comm -12 <(cd spring-framework-petclinic/; git rev-list --all | sort) <(cd spring-petclinic; git rev-list --all | sort) | wc -l
427