2010-01-25

Subversion 用户眼中的 Git (4): 全局版本号和全球版本号

Subversion 的全局版本号和 CVS 的每个文件都独立维护一套版本号相比,是一个非常大的进步。在看似简单的全局版本号的背后,是 Subversion 提供对于事物处理的支持,每一个事物处理(即一次提交)都具有整个版本库全局唯一的版本号。 Git 的版本号则更进一步,版本号是全球唯一的。也可以说是全宇宙唯一的。 :-D Git 对于每一次提交,要将包括作者,提交内容等在内的信息整个作一个 SHA1 哈希,进而得到版本号。版本号得到一个 40 位十六进制字串。 什么?40位长的版本号?

全球唯一的版本号,您认为多长合适?

对于一个分布式的版本控制系统,每个人都可以独立创建提交,每次提交都形成一个新的版本号,每个版本号都不能够重复。使用摘要是解决唯一性的好方法,而当前来看使用 SHA1 是非常稳妥的。而 SHA1 就是一个 40位的十六进制的字串。 要是 SHA1 发生冲突了呢?即使真的发生冲突,还可以使用更加复杂的摘要算法,采用更长的摘要。如:SHA-224, SHA-256, SHA-384,  SHA-512, ...

SVN 的版本号是连续的,可以预判下一个版本号,而 Git 的版本号则不是

因为 subversion 是集中式版本控制,当然很容易实现版本号的连续性。Git 是分布式的版本控制而且 Git 采用 40 位长的哈希值作为版本号,每个人的提交都是各自独立完成的,没有先后之分(即使提交有先后之分,也由于PUSH/PULL的方向和时机而不同)。 有人可能用过 Hg (Mercurial),可能会说 Hg 虽然也用 SHA1 摘要,但是还同时提供一个递增的数字版本号哇,为什么 Git 没有? 我是这么认为的:
  • 首先 Hg 的递增数字版本号不是全局或者全球唯一的,而只是在本地版本中存在的一个指向全球版本号的别名而已;
  • Hg 可以这么做,而 Git 没有这么做的原因是 Git 实现了真正的分支管理,而 Hg 版本库本身没有实现真正的分支管理;
Git 的版本号虽然不连续,但是是有线索的,即每一个版本都有对应的父版本(一个或者两个),进而可以形成一个复杂的提交链

Git 的版本号简化

如果每次需要引用使用版本号的时候,都使用 40 位的十六进制字符,那不是太麻烦了么? Git 可以使用从左面开始任意长度的字串作为简化版本号,只要该简化的版本号不产生歧义。一般采用7位的短版本号。 Git 还可以使用 tag 来创建别名,即里程碑。

安全性,是 Git 版本号设计的另外一个考虑

和 subversion 不同,Git 版本库可以被任何人克隆,如果没有安全性的设计,克隆版本库后伪造提交数据再克隆给其他人,那么就是版本控制的灾难。 使用 SHA1 摘要作为版本号,同时解决了版本号唯一性和提交数据的安全性这两个问题。一单数据被伪造,将造成和 SHA1 摘要的版本号不符,引发异常。
blog comments powered by Disqus