我发现很难围绕Git如何创建完全独特的哈希,即使在前4个字符中也不允许相同的哈希。我只能使用前四个字符在Git Bash中调用提交。是否在算法中明确决定第一个字符是“超” - 唯一且不会与其他类似的哈希冲突,或者算法是否以相同的方式生成哈希的每个部分?
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的巨大不可能性。
2017年4月:请注意在所有shattered.io episode(谷歌实现SHA1碰撞)之后,20字节格式不会永远存在。
第一步是用一个通用对象替换整个Git代码库中的硬代码的unsigned char sha1[20]
,该对象的定义可能在将来发生变化(SHA2?,Blake2,...)
请参阅commit e86ab2c撰写的brian m. carlson (bk2204
)(2017年2月21日)。
将
unsigned char [20]
的剩余用途转换为struct object_id
。
这是commit 5f7817c开始的brian m. carlson (bk2204
)(2015年3月13日)正在进行的努力的一个例子,cache.h
的v2.5.0-rc0:
/* 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个第一个字符也不足以保证唯一性,正如我在“How much of a git sha is generally considered necessary to uniquely identify a change in a given codebase?”中解释的那样。
使用Git 2.16(2018年第一季度)更新2017年12月:支持替代SHA的努力正在进行中:请参阅“Why doesn't Git use more modern SHA?”。
您将能够使用另一个哈希:SHA1不再是Git的唯一哈希。
更新2018-2019:已经在Git 2.19 +中进行了选择:SHA-256。 见“hash-function-transition”。
这还没有激活(意味着git 2.21仍在使用SHA1),但代码正在完成以支持将来的SHA-256。