这是2007年的演讲,但是仍然值得一看。

git一直有对初学者不友好的名声,主持人一开始就调侃了一句:

It was especially designed to make you feel less intelligent than you think you were.

git最初被设计用来管理Linux内核,而Linus作为内核负责人,当然是以方便自己使用的角度出发来设计git。

Linux说出了自己对版本管理的三点要求:

If you are not distributed, you are not worth using.

If you perform badly, you are not worth using.

If you can not guarantee that the stuff I put into the SCM come the exactly the same. You are not worth using.

为什么像CVS这些集中式的版本管理工具无法用来管理Linux内核呢?Linus给出了答案,主要是因为没有去中心化。

首先,使用中心仓库会产生一个巨大的问题:谁有权限向中心仓库提交改动?像Linux内核这种参与者非常多的项目,权限管理需要消耗许多精力,而且容易演变成政治问题。比如经常会有像“凭什么给他权限而不是给我权限”的问题无端消耗管理者的精力却没有好结果。

分布式的好处是每个仓库都是一个对等的仓库,每个人可以在自己本地仓库上提交改动。当改动足够成熟的时候再向管理者发起请求,让管理者把改动合并到上游仓库中。这是一种十分可行的模式,能够把大家的精力集中在把事情做好上。管理者也更容易发现那些水平比较高的代码提交者,信任分配也就更容易。

中心仓库的另一个问题是会限制工作地点。一般中心仓库要求通过网络连接来访问,这限制了开发者可能的工作地点。即便是在这个wifi遍布街头的时代,期望能够随时随地连接到中心仓库修改代码也是不太现实的。Linux内核的开发者分布在世界各地,不是所有的地方都有很好的网络连接。

能够从本地而不是从网络查询版本历史对使用效率的提升有显而易见的帮助。作为内核维护者,每天都要合并许多人的代码,可能会影响成百上千的文件,合并代码这个操作的快慢会直接影响工作心情。如果所有的版本历史都存放在本地,执行合并操作的时候就不需要通过网络查询,效率自然提高。再加上精心优化过的代码,git的合并操作可以在秒级完成,远非其他集中式的版本管理工具所能及。

当合并变得容易了,人们就更喜欢使用分支了。分支其实是一种是天然的工作模式,无论你使用哪一种版本管理工具,当你把代码检出到本地工作目录的时候其实创建了一个分支。这个工作目录就是一个分支,只不过它没有名字。既然创建分支是一种本质的需求,为什么不使其变得更容易呢?我们在使用git的时候往往会创建许多分支,因为创建分支十分容易,合并不同分支的操作也十分快速。很多版本管理工具虽然也支持分支,但是由于对合并操作支持得不好,在这些版本管理工具下急性分支操作并不是一种很好的体验。

分布式的系统天然具有易于备份的属性。如果许多人都克隆了你的仓库,当不幸硬盘毁坏的时候,只要从别人那把仓库克隆回来就可以了。当然,为了保证从别人那克隆回来的仓库不是被别人恶意篡改过的,git对存道仓库里面的内容都进行了完整性保护,不论文件,目录或版本修订都是用sha1算法做过摘要的,无法随意仿照。