什么';两个git commit有相同的'abbrev commit'的可能性`
两个git提交有相同的什么';两个git commit有相同的'abbrev commit'的可能性`,git,Git,两个git提交有相同的abbrev提交 我看到git history默认显示git abbrev commit以简化和美观。 但是在一次git回购中出现两个相同的abbrev提交的可能性有多大。 或者更确切地说:在回购协议中发生SHA1冲突的可能性相同 当git命令返回缩略引用列表时,如果发现两个缩略语(哈希摘要的前缀)相同,它会将完整SHA1哈希中的更多字符添加到这些特定引用中,直到它们不再相同。有几种不同的方法来回答这个问题。你可以用数学告诉你在各种条件下的机会。另一个问题是问Git实际上做
abbrev提交
我看到git history默认显示git abbrev commit以简化和美观。
但是在一次git回购中出现两个相同的abbrev提交的可能性有多大。
或者更确切地说:在回购协议中发生SHA1冲突的可能性相同
当git命令返回缩略引用列表时,如果发现两个缩略语(哈希摘要的前缀)相同,它会将完整SHA1哈希中的更多字符添加到这些特定引用中,直到它们不再相同。有几种不同的方法来回答这个问题。你可以用数学告诉你在各种条件下的机会。另一个问题是问Git实际上做了什么,但当问这个问题时,答案取决于您特定的Git版本
数学答案
这种可能性取决于缩写的长度和存储库中对象的数量。(在某些情况下,如果您知道所需的对象类型,如果潜在匹配描述了不同的对象类型,您可以消除冲突的歧义。在这种情况下,您可以简单地减少下面公式中的值n。)
因为StackOverflow没有格式化LaTeX,所以我在这里有一个截图,来自我自己(正在编写)的书的第77页。我做的有点太大了抱歉:
要找到所需的数字,请将n和r替换为正确的值并计算p-bar,然后从1中减去该值。N是对象数:
$ git count-objects -v
count: 49
size: 568
in-pack: 307916
packs: 40
size-pack: 176024
prune-packable: 0
garbage: 0
size-garbage: 0
这个存储库大约有300000个对象(大多数是打包的;只有49个松散的对象),所以n大约是300k。您的存储库当然会有所不同
然后,插入r的正确值。如果使用完整散列,则r的值为2160,或14615011633309002918203684832716283019655932542976。如果将哈希值缩写为四个字符,这是Git将接受的最小输入,即216或65536,因为每个字符提供4位。完整散列长度为40个字符,因此在完整散列公式中为160个字符
Git实际上做什么
如果使用git-rev-parse--short=number
或git-log--abbrev=number--abbrev-commit
,则由您选择长度。如果您没有提供一个数字,Git会使用一个不合适的公式来选择一个数字。1但它不仅仅使用那个数字
现代Git检查缩写哈希在当前数据库中是否唯一。这不是一个概率猜测,它只是一个文字测试,在循环中执行:
length = <whatever>
loop {
generate short hash using <length> characters
is short hash unambiguous? if so, we're done - exit the loop
increment length
}
长度=
环路{
使用字符生成短哈希
short hash是否明确无误?如果是,则完成-退出循环
增量长度
}
这样就不可能与现在的对象发生碰撞
不幸的是,如果再添加一个对象,新对象可能会与基于旧对象生成的缩写哈希冲突。使用上面的公式计算这个概率,知道所有现有的键都没有冲突,加上缩写哈希长度所隐含的r值。这可能还是相当不错的,因为即使是4个字符,你也会得到65536中的1个。但请注意,随着添加更多对象,情况会迅速恶化
当Linus Torvald的第一段代码进入Git 2.11时,循环签入代码就存在了。我不确定一个人要走多远才能回到它没有发生的地方,但在一些非常古老的Git版本中肯定没有发生过
1在Git 2.11中,Git使用了一个事实,即对于大量n个键,50%的冲突率发生在n=sqrt(r)处。Linus Torvalds添加了以下代码:
+ if (len < 16 && !status && (flags & GET_SHA1_AUTOMATIC)) {
+ unsigned int expect_collision = 1 << (len * 2);
+ if (ds.nrobjects > expect_collision) {
+ default_automatic_abbrev = len+1;
+ return SHORT_NAME_AMBIGUOUS;
+ }
+ }
+if(len<16&&!status&&(flags&GET\u SHA1\u AUTOMATIC)){
+无符号整数预期碰撞=1预期碰撞){
+默认值\u automatic\u abbrev=len+1;
+返回短\u名称\u不明确;
+ }
+ }
对于Git2.11,这是一个很好的例子。随后在年对其进行了改进。但50%的概率太高了。正如我在“”中提到的,只需拨打
通过输入一个太短的长度,您将强制Git返回实际的最小长度,这保证了存储库的SHA1唯一性
获取git rev parse--short=4的返回sha1的最小长度,您就不会有任何问题。Slim。它是一个随机散列,所以它非常小。可能是由于没有压缩提交而意外导致的。我得等我自己去弄清楚我是怎么做到的。我只是在猜测