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

问题描述 投票:15回答:2

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

git algorithm hash git-hash
2个回答
28
投票

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的巨大不可能性。


4
投票

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。

© www.soinside.com 2019 - 2024. All rights reserved.