Git如何创建唯一的提交哈希值,主要是前几个字符?

时间:2016-01-13 10:26:54

标签: git algorithm hash git-hash

我发现很难理解Git如何创建完全独特的哈希,即使在前4个字符中也不允许相同的哈希值。我只能使用前四个字符在Git Bash中调用提交。在算法中是否明确决定第一个字符是" ultra" -unique并且不会与其他类似的哈希冲突,或者算法是否以相同的方式生成哈希的每个部分?

2 个答案:

答案 0 :(得分:27)

Git使用以下信息生成sha-1:

  • 提交的源代码树(解析所有子树和 blob)
  • 父提交sha1
  • 作者信息
  • 提交者信息(对,那些不同!)
  • 提交消息

(关于完整的解释;看here)。

Git 保证前4个字符是唯一的。在chapter 7 of the Pro Git Book中写道:

  

Git可以找出SHA-1值的简短唯一缩写。   如果将--abbrev-commit传递给git log命令,输出将会   使用较短的值但保持它们的独特性;它默认使用七   字符,但如果需要保持SHA-1,它们会更长   明确的:

所以Git只要缩写,只要有必要就可以保持唯一。他们甚至注意到:

  

通常,八到十个字符绰绰有余   在一个项目中。

     

作为一个例子,Linux内核,这是一个非常大的项目   超过450k提交和360万对象,没有两个对象   SHA-1重叠超过前11个字符。

所以事实上他们只是依赖于具有完全相同(X的第一个字符)sha的伟大的不可能性

答案 1 :(得分:4)

四月2017:请注意在全部shattered.io episode之后(Google实现了SHA1碰撞),20字节格式不会永远存在。

第一步是用一个通用对象替换整个Git代码库中的硬代码unsigned char sha1[20],该对象的定义可能在将来发生变化(SHA2?,Blake2,... )

commit e86ab2cbrian m. carlson (bk2204)(2017年2月21日)commit 5f7817c

  

unsigned char [20]的剩余使用转换为struct object_id

这是brian m. carlson (bk2204)(2015年3月13日)cache.h针对v2.5.0-rc0 How much of a git sha is generally considered necessary to uniquely identify a change in a given codebase?开始的持续努力的一个示例:

/* The length in bytes and in hex digits of an object name (SHA-1 value). */
#define GIT_SHA1_RAWSZ 20
#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)

struct object_id {
    unsigned char hash[GIT_SHA1_RAWSZ];
};

并且不要忘记,即使使用SHA1,4个第一个字符也不足以保证唯一性,正如我在“Why doesn't Git use more modern SHA?”中解释的那样。

2017年12月更新与Git 2.16(2018年第一季度):正在努力支持替代SHA:请参阅“SHA-256”。

您将能够使用另一个哈希:SHA1不再是Git的唯一哈希。

更新2018-2019 :已在Git 2.19 +中做出选择: hash-function-transition
请参阅“sbt-dotty”。

这还没有激活(意味着git 2.21仍在使用SHA1),但代码正在完成以支持将来的SHA-256。