通常*需要多少个git sha来唯一标识给定代码库中的更改?

例如,如果要构建一个目录结构,该目录结构为Git存储库中的提交命名了一个目录,并且您希望它足够短以至于不让您流血,但又要足够长以使它碰撞的机会可以忽略不计,通常需要多少SHA子字符串?


假设我要唯一标识此更改:https : //github.com/wycats/handlebars.js/commit/e62999f9ece7d9218b9768a908f8df9c11d7e920


我最多只能使用前四个字符:https : //github.com/wycats/handlebars.js/commit/e629


但是我觉得那会很冒险。但是假设某个代码库可能在几年内可能会发生(例如)3万次更改,那么如果我使用8个字符,发生冲突的机会是多少?12点?是否存在通常被认为可以接受的数字?


开满天机
浏览 893回答 3
3回答

犯罪嫌疑人X

Pro Git手册的第7章实际上回答了这个问题:通常,八个到十个字符足以在一个项目中唯一。最大的Git项目之一Linux内核开始需要在40个字符中保持12个字符以保持唯一性。短SHA的Git默认值为7位数,因此对于大多数项目来说都可以。如前所述,内核团队增加了几次,因为有数十万次提交。因此,对于您的约3万次提交,8或10位数字应该是完美的。

猛跑小猪

您可以要求git rev-parse --short最短但唯一的SHA1。请参阅“ git从常规哈希中获取短哈希 ”git rev-parse --short=4 921103db8259eb9de72f42db8b939895f565148992110如您在示例中所见,即使我指定的长度为4,SHA1的长度也为5。对于大型存储库,自2010年以来7个还不够,因此请 Linus Torvalds本人提交dce9648(git 1.7.4.4,2010年10月):默认值7来自git开发的相当早的时候,当时7个十六进制数字很多(它涵盖了大约250+百万个哈希值)。那时,我认为65k修订版本很多(这是我们在BK中要达到的版本),每个修订版本通常大约有5-10个新对象,所以一百万个对象是一个很大的数目。(BK = BitKeeper)这些天来,内核甚至不是最大的Git项目,甚至内核约220K版本(多比BK树曾是大),我们正在接近200万级的对象。那时,对于许多字符来说,七个十六进制数字仍然是唯一的,但是当我们谈论的是对象数量和散列大小之间仅两个数量级的差异时,截断的散列值将存在冲突。它甚至不再接近于不现实-它一直在发生。我们都应该增加一个不切实际的很小的默认缩写,并增加人们在git config文件中设置自己的默认每个项目的方法。core.abbrev设置长度对象名称的缩写。如果未指定,则许多命令缩写为7个十六进制数字,这可能不足以使缩写对象名称在足够长的时间内保持唯一。environment.c:int minimum_abbrev = 4, default_abbrev = 7;注意:如下面的marco.m所评论,在提交a71f09f中的同一Git 1.7.4.4中core.abbrevLenght被重命名。core.abbrev重命名core.abbrevlength为core.abbrev--abbrev=$n毕竟它对应于命令行选项。最近,Linus在提交中提交了e6c587c(针对Git 2.11,2016年第4季度):(如Matthieu Moy的回答中所述)在相当早的日子里,我们以某种方式决定将对象名称缩写为7个十六进制,但是随着项目的发展,越来越早地看到这么短的对象名称并记录在日志消息中的可能性越来越小。当前,Linux内核项目需要11到12个十六进制数,而Git本身需要10个十六进制数来唯一标识它们具有的对象,而许多较小的项目可能仍然可以使用原始的7十六进制数。单一尺寸并不适合所有项目。引入一种机制,在该机制下,我们会在第一次请求时估计存储库中的对象数量,以使用默认设置来缩写对象名称,并为存储库提出一个合理的默认值。基于预期,2^(2N)当使用对象名称缩短到前N位时,在存储库中会与对象发生冲突,请使用足够数量的十六进制数来覆盖存储库中的对象数量。我们在缩写名称中添加的每个十六进制数字(4位)使我们可以在存储库中拥有四倍(2位)的对象。参见Linus Torvalds()的commit e6c587c(2016年10月1日)。 参见Junio C Hamano()提交的commit 7b5b772和commit 65acfea(2016年10月1日)。(通过合并JUNIOÇ滨野- -在提交bb188d0,2016年10月3日)torvaldsgitstergitster这个新属性(猜测SHA1缩写值的合理默认值)直接影响Git如何计算自己的版本号以进行发布。

aluckdog

这被称为生日问题。对于小于1/2的概率,可以将碰撞概率近似为p〜=(n 2)/(2m)其中n是项目数,m是每个项目的可能性数。十六进制字符串的可能数目为16 c,其中c为字符数。因此对于8个字符和30K次提交30K〜= 2 15P〜=(N 2)/(2M)〜=((2 15)2)/(2 * 16 8)= 2 30 /2 33 =⅛增加到12个字符P〜=(N 2)/(2M)〜=((2 15)2)/(2 * 16 12)= 2 30 /2 49 = 2 -19
打开App,查看更多内容
随时随地看视频慕课网APP