在Git中,长哈希值和短哈希值有什么区别?

62

这里是Git的长哈希值:

提交 c26cf8af130955c5c67cfea96f9532680b963628

合并:8654907 37c2a4f

作者:nicolas

日期:2017年4月26日,星期三,下午1:28:22 -0400

这里是短哈希值:

输入图像描述


8
短哈希是散列值的前7个字符。c26cf8af130955c5c67cfea96f9532680b963628的短哈希在第二行显示为c26cf8a。参见文档:"只要您提供的部分SHA-1至少有四个字符且不含歧义,Git就足够聪明,可以确定您打算键入的提交版本。" - jschnasse
不,长哈希值不是引用。它是所代表对象(在这种情况下是提交)的实际内容的内容哈希值。Git中的所有内容都有哈希值(例如树、文件、标签等),而不仅仅是哈希值。引用(refs)则完全是另一回事,它们是一对(名称,哈希值),为我们提供了一种良好的人类兼容方式来处理它们。 - AnoE
4个回答

66
为了更加深入地说明为什么短哈希很有用,以及为什么通常不需要长哈希,这与 Git 如何存储内容有关。 c26cf8af130955c5c67cfea96f9532680b963628 可能存储在两个位置之一。它可能在文件 .git/objects/c2/6cf8af130955c5c67cfea96f9532680b963628 中。请注意,前两个字符 c2 组成一个目录,其余是文件名。由于许多文件系统在一个目录中有太多的文件时性能会降低,因此这可以防止任何一个目录中有太多的文件,并使这个小的目录数据库保持高效。
只用短哈希值 c26cf8a,Git 就可以执行等价于 .git/objects/c2/6cf8a* 的操作,这可能是一个单独的文件。由于对象被细分为子目录,所以要查找是否有多个匹配项时需要查看的文件名并不多。
单独使用c26cf8a就包含了足够多的可能性,16^7 或 2^28 或 268,435,456,因此极不可能有另一个提交共享该前缀。
基本上,Git 使用文件系统本身作为简单的键/值存储,并且可以查找部分键而无需扫描整个键列表。
这是一种存储对象的方式。越来越多地,Git 将其对象存储在包文件中。这是一种非常高效的方式,只存储文件之间的差异。不时地,您的 Git 存储库将检查 .git/objects 中的内容,并仅将差异存储在 .git/objects/pack/pack-<checksum> 中。
这是一种二进制格式,我在此不会做更详细的介绍,我自己也不太理解。 :)

14

短哈希就是完整哈希值的前7个字符。

在您的屏幕截图中圈出的提交正下方,您可以看到一个标记为c26cf8a的提交。这应该是您要寻找的提交c26cf8af130955c5c67cfea96f9532680b963628


7
默认的缩写提交哈希长度是不确定的。看起来,它取决于历史记录的长度。我知道有7、8、9个字符的情况。使用 --abbrev 参数可以强制设置该长度。 - dyomas

10

短哈希是散列的前七个字符。c26cf8af130955c5c67cfea96f9532680b963628的短哈希在第二行中为c26cf8a。请参见文档

如果提供了前几个字符,只要您的部分SHA-1长度至少为四个字符且无歧义,Git就足够聪明,可以找出您打算键入的提交。


2
短哈希只是原始(长)哈希的缩写版本。原始Git哈希长度为40字节,而短哈希只有8字节长。但是,由于难以管理(在使用打字或显示方面),因此采用了短版本。
这种方法在几乎所有项目中都使用哈希,无论是为了完整性(软件包分发)、版本控制(Git和SVN)还是分层架构(Docker)。

短整型实际上不是7个字节长,而是28位吗?长整型是160位吗? - grenix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接