我发现很难理解Git如何创建完全独特的哈希,即使在前4个字符中也不允许相同的哈希值。我只能使用前四个字符在Git Bash中调用提交。在算法中是否明确决定第一个字符是" ultra" -unique并且不会与其他类似的哈希冲突,或者算法是否以相同的方式生成哈希的每个部分?
答案 0 :(得分:27)
Git使用以下信息生成sha-1:
(关于完整的解释;看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 e86ab2c见brian 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。