为什么git为什么使用哈希而不是修订号?


80

我一直想知道为什么git更喜欢哈希而不是版本号。修订版本号更清晰,更容易引用(在我看来):告诉某人查看修订版本1200或提交92ba93e之间是有区别的!(仅举一个例子)。

那么,这种设计有什么理由吗?


3
您可以使用“ v1.0”标记一个提交,然后通过该标记引用该提交。见git-scm.com/book/en/v2/Git-Basics-Tagging
Michael Durrant

Answers:


114

单一的,单调增加的修订版本号仅对集中式版本控制系统才有意义,在该系统中,所有修订版本都流到可以跟踪和分配编号的单个位置。一旦进入DVCS世界,那里存在大量的存储库副本,并且在任意工作流中都将更改从中拉出并推送到它们,那么该概念就不再适用。(例如,没有一个地方可以分配修订号-如果我分叉您的存储库,而您决定在一年后决定进行更改,那么系统如何确保我们的修订号不冲突?)


11
您可能想看看Bazaar的方式 -仍然保持修订号的DVCS。唯一的保证是版本号在分支中是唯一的。
krlmlr

3
@krlmlr- Person 1: "Hey, <P2>, what was revision 12345 for?" P2: "Revision 12345 was commited by <P3>." P3: "I don't have a revision 12345..."如果我没记错的话,Mercurial也有类似的问题。另一方面,如果他们使用的是git,则每个提交的引用都相同。
2013年

1
@Izkata:P1: "Do you have revision with the GUID gdlmsnblngoijlafd-35345-fg?"...集市上仍然有GUID ...
krlmlr

5
@Izkata水银并不会有类似的问题。他们使用哈希,就像git。他们还提供了仅限本地的转速编号,以方便键入。
Hank Gay

1
使用git时,哈希的前5个字符通常足够唯一,可以使用简写形式表示完整的修订ID。
mendota '16

40

您需要在分布式系统中使用哈希。假设您和一位同事都在同一个存储库上工作,并且都在本地提交更改,然后将其推送。如果谁都没有对方的知识,谁将成为修订号1200,谁是修订号1201?唯一可行的技术解决方案是使用已知方法创建更改的哈希,然后基于该链接进行链接。

有趣的是,HG确实支持版本号,但是它们明确地是仅用于本地的功能-您的存储库有一组,而您的同事的存储库将具有不同的组,具体取决于它们的推入和拉出方式。但是,它的确使命令行用法比Git更友好。


34

数据的完整性。

我谨不同意当前的答案。DVCS不需要哈希,请参见Bazaar方法。您也可以使用任何其他类型的全局唯一标识符执行操作。哈希是保证数据完整性的一种措施:它们表示哈希所引用的对象(commit,tree等)中包含的信息的摘要。尽管并非不可能,但是在不更改哈希值的情况下更改内容(即,前图像攻击碰撞攻击)被认为是困难的。(如果您真的很感兴趣,请参阅Marc Stevens2011年论文)。

因此,通过对象的SHA哈希引用对象可以检查内容是否已被篡改。并且,由于它们(几乎)保证是唯一的,因此它们也可以用作修订标识符,因此很方便。

有关更多详细信息,请参见Git书的第9章


8
这不是安全措施,因为可以很容易地为修改的提交重新计算哈希。它仅用于完整性,以验证对计算出的哈希内容-看到此评论从Linus Torvalds的在Git的使用SHA-1。

@Lee:如果Chuck的存储库与Alice和Bob的修订哈希不同,则可以确保Chuck也具有不同的内容。另一方面,对于Chuck来说,很难制造一个内容不同的存储库,这些存储库的修订哈希值看起来是相同的。
krlmlr

@李:错过了您的链接。那么我们称其为“数据完整性” ...
krlmlr

应该是正确的答案
SuperUberDuper '16

8

用外行的话来说:

  • 散列几乎是唯一的。它不能保证,但它是非常不可能的相同SHA的是针对不同的内容生成。实际上,对于给定的项目,您可以将其视为独特的。
  • 使用修订版号,您将必须使用名称空间,以便专门引用修订版1200。
  • Git可以分布式和/或集中式工作。那么,如何获得正确且唯一的修订版本号?
  • 同样使用修订版号会产生错误的说法,即较新的修订版应具有更高的编号,而由于分支,合并,重新定基等原因,这将不成立。
  • 您始终可以选择将标签提交。

32
不保证是唯一的,只是极有可能是唯一的。:)
dsw88

@ mustang2009cobra是的。
TulainsCórdova'13

1
我的更改有可能因为哈希值未更改而未被接受。两颗流星更有可能同时击中我的计算机和具有存储库的计算机,从而摧毁了计算机并杀死了所有参与其中的人。
gnasher729


1

哈希不是分布式VCS的唯一解决方案。但是,当处理分布式系统时,只能记录事件的部分顺序。(对于VCS,该事件可以是提交。)这就是为什么无法单调增加修订版本号的原因。通常我们采用矢量时钟(或矢量时间戳)之类的东西来记录这种偏序关系。这是Bazaar中使用的解决方案。

但是为什么Git不使用向量时钟而是使用哈希呢?我认为根本原因是摘樱桃。当我们在存储库上执行cherry-pick时,提交的部分顺序正在更改。必须重新分配某些提交的矢量时钟,以表示新的部分排序。但是,在分布式系统中进行这种重新分配会导致矢量时钟不一致。那是哈希处理的真正问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.