在我的仓库中,最长的哈希前缀必须要多长时间才能防止任何重叠?

jub*_*0bs 10 git sha1 linux-kernel git-log git-rev-list

--abbrev-commit标志可以与git log和一起使用,git rev-list以显示部分前缀,而不是提交对象的完整40个字符的SHA-1哈希值.根据Pro Git的书,

它默认使用七个字符,但如果有必要使它们更长,以保持SHA-1明确[...]

另外,短SHA的长度至少为4个字符.仍然根据Pro Git的书,

通常,八到十个字符足以在项目中独一无二.

例如,Linux内核是一个相当大的项目,具有超过450k的提交和360万个对象,没有两个对象的SHA-1重叠超过前11个字符.

由于防止提交对象的所有前缀哈希值之间的任何重叠所需的最长前缀的长度(11,在Linux内核的情况下)是回购邮件大小的粗略指示,我想以编程方式确定相应的数量.我自己的本地存储库.我怎样才能做到这一点?

jub*_*0bs 16

以下shell脚本在本地存储库中运行时,会打印所需的最长前缀的长度,以防止该存储库的提交对象的所有前缀哈希值之间出现任何重叠.

MAX_LENGTH=4;

git rev-list --abbrev=4 --abbrev-commit --all | \
  ( while read -r line; do
      if [ ${#line} -gt $MAX_LENGTH ]; then
        MAX_LENGTH=${#line};
      fi
    done && printf %s\\n "$MAX_LENGTH"
  )
Run Code Online (Sandbox Code Playgroud)

我上次编辑此答案时,脚本已打印出来


jav*_*ett 8

Jubob的剧本很棒,很受欢迎.

如果你想了解minimum-commit-hash-length的分布,你可以运行这个单行:

git rev-list --abbrev=4 --abbrev-commit --all | ( while read -r line; do echo ${#line}; done; ) | sort -n | uniq -c
Run Code Online (Sandbox Code Playgroud)

对于今天的git项目本身(git-on-git),这会产生类似于:

 1788 4
35086 5
 7881 6
  533 7
   39 8
    4 9
Run Code Online (Sandbox Code Playgroud)

...产生1788次提交,可以用4 -char哈希(或更低,这是Git的最小缩写)唯一地表示,4次提交需要6到40个字符的哈希,以便唯一地选择它们.

相比之下,一个更大的项目,如Linux内核,今天有这样的分布:

6179   5
446463 6
139247 7
10018  8
655    9
41    10
3     11
Run Code Online (Sandbox Code Playgroud)

因此,对于具有近500万个对象和600k提交的数据库,目前有3个提交需要40个十六进制数字中的11个来区分它们与所有其他提交.