-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy path2010-01-25-337.html
More file actions
37 lines (27 loc) · 3.22 KB
/
2010-01-25-337.html
File metadata and controls
37 lines (27 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
---
layout: post
title: "Subversion 用户眼中的 Git (4): 全局版本号和全球版本号"
---
Subversion 的全局版本号和 CVS 的每个文件都独立维护一套版本号相比,是一个非常大的进步。在看似简单的全局版本号的背后,是 Subversion 提供对于事物处理的支持,每一个事物处理(即一次提交)都具有整个版本库全局唯一的版本号。
Git 的版本号则更进一步,版本号是全球唯一的。也可以说是全宇宙唯一的。 :-D Git 对于每一次提交,要将包括作者,提交内容等在内的信息整个作一个 SHA1 哈希,进而得到版本号。版本号得到一个 40 位十六进制字串。
什么?40位长的版本号?
<span id="more-337"></span>
<h2>全球唯一的版本号,您认为多长合适?</h2>
对于一个分布式的版本控制系统,每个人都可以独立创建提交,每次提交都形成一个新的版本号,每个版本号都不能够重复。使用摘要是解决唯一性的好方法,而当前来看使用 SHA1 是非常稳妥的。而 SHA1 就是一个 40位的十六进制的字串。
要是 SHA1 发生冲突了呢?即使真的发生冲突,还可以使用更加复杂的摘要算法,采用更长的摘要。如:SHA-224, SHA-256, SHA-384, SHA-512, ...
<h2>SVN 的版本号是连续的,可以预判下一个版本号,而 Git 的版本号则不是</h2>
因为 subversion 是集中式版本控制,当然很容易实现版本号的连续性。Git 是分布式的版本控制而且 Git 采用 40 位长的哈希值作为版本号,每个人的提交都是各自独立完成的,没有先后之分(即使提交有先后之分,也由于PUSH/PULL的方向和时机而不同)。
有人可能用过 Hg (Mercurial),可能会说 Hg 虽然也用 SHA1 摘要,但是还同时提供一个递增的数字版本号哇,为什么 Git 没有?
我是这么认为的:
<ul>
<li>首先 Hg 的递增数字版本号不是全局或者全球唯一的,而只是在本地版本中存在的一个指向全球版本号的别名而已;</li>
<li>Hg 可以这么做,而 Git 没有这么做的原因是 Git 实现了真正的分支管理,而 Hg 版本库本身没有实现真正的分支管理;</li>
</ul>
Git 的版本号虽然不连续,但是是有线索的,即每一个版本都有对应的父版本(一个或者两个),进而可以形成一个复杂的提交链
<h2>Git 的版本号简化</h2>
如果每次需要引用使用版本号的时候,都使用 40 位的十六进制字符,那不是太麻烦了么?
Git 可以使用从左面开始任意长度的字串作为简化版本号,只要该简化的版本号不产生歧义。一般采用7位的短版本号。
Git 还可以使用 tag 来创建别名,即里程碑。
<h2>安全性,是 Git 版本号设计的另外一个考虑</h2>
和 subversion 不同,Git 版本库可以被任何人克隆,如果没有安全性的设计,克隆版本库后伪造提交数据再克隆给其他人,那么就是版本控制的灾难。
使用 SHA1 摘要作为版本号,同时解决了版本号唯一性和提交数据的安全性这两个问题。一单数据被伪造,将造成和 SHA1 摘要的版本号不符,引发异常。