Git15周年:当年的分道扬镳,成就了今天的开源传奇
我们知道,所有的软件项目在整个生命周期中都要经过不断迭代,在一个又一个的新版本中完善自己的功能。开源项目更是如此,一个健康的开源项目,在“集市”模式下接受来自世界各地开发者提交的代码,版本更新频率通常更高。如何管理项目的版本更新,是项目开发、维护过程中必须考虑的问题。
什么是版本控制工具
在开始我们的故事之前,首先让我们来认识一下版本控制工具。版本控制的核心述求是历史纪录查询和实现协同开发。以开源项目来说,在多人协作开发的模式下,每个人都向服务器提交自己的文件,就可能存在着代码被多次修改、替换的风险,但是版本控制能够在每次更新操作后进行相应的记录。一旦发生误操作,开发者能够根据服务器中的版本记录,将项目恢复到出现问题之前的其他版本。因此,借助版本控制技术,软件开发项目可以被分割为若干模块,每个模块并行地进行开发工作,从而有效地提高了整体编程效率。
主流的版本控制工具主要分为两种,即集中式与分布式。
集中式版本控制工具类似网吧的管理系统,所有项目的历史文件与版本信息都存放在服务器上,而客户端就只能保存当前的状态信息。这种所有鸡蛋装在一个篮子里的模式缺点非常明显,一旦服务器损坏,项目所有的历史数据就会丢失,因此需要大规模的安全备份。比较有代表性的集中式版本控制工具有SVN、VSS、CVS等。
分布式版本控制工具最大的特性就是任意客户端之间可以互联,当然也包括服务器。这样一来,开发者的客户端本地也存有项目完整的历史记录,当有一个客户端损坏时,可以从另一个没有被损坏的客户端中提取历史数据,恢复之前的状态。在协同开发时,各个客户端之间可以很好地同步开发进度,避免出现重复提交等问题。
毫无疑问,分布式版本控制工具拥有更为先进的理念,其诞生的过程也是得益于网络通信技术的普及与开源社区的蓬勃发展。
天才的帮手
我们的故事始于1991年,大名鼎鼎的开源项目Linux问世,作者LinusTorvalds一跃成为IT界的大明星,被人们称为天才。由于当时Linux社区仍采用传统的集中式版本管理,开发者提交的patch都汇集到Linus这里,让他肩上的担子很重。
(LinusTorvalds)
在项目早期,Linus以最原始的人力来完成Linux版本管理工作,包括逐条细看每个patch、手动合并开发者提交的代码、更新版本历史信息等。由于这段“痛苦”的经历,Linus本人曾多次公开吐槽“代码管理是计算机领域最无趣的事”……
然而随着社区的逐渐壮大,Linux的系统变得越来越庞大,代码越来越繁杂,继续依靠手动合并代码显然已经不太现实。
1999年,一家名为BitMover的公司发布了一款收费的分布式版本控制软件BitKeeper,BitMover的CEOLarry给Linux社区特别提供了一个可以免费使用的版本,期望BitKeeper能帮助Linus免于陷入不断加重的Linux内核管理工作中,但条件是不能破解这款产品。
Linus在使用BitKeeper之后不久就爱上了它,直言其是“Besttoolforthejob”。BitKeeper让每个开发者都拥有自己的主副本(mastercopy),完整的副本意味着可以在本地做所有事,而不是所有的patch只能提交到服务器(Linus)这里。于是,Linus可以把一些patch的审查工作交给Liunx子系统的维护者们,对于比较值得信任的维护者甚至不需要他自己再审查一遍,而他只需要对一些自己不太信任的维护者“重点关照”即可。2002年,Linux内核主线代码就全面开始使用BitKeeper。
尽管BitKeeper的出现赋予了Linux社区更好的协同开发能力,让Linux内核的开发效率成倍提高,但其闭源的特性仍然让Linus在开源界遭到了一些非议。开源泰斗RSM就严厉批评Linus不该使用一款非自由的软件来管理世界上最大的开源项目。这些负面的声音也为之后Linux与BitKeeper的分道扬镳埋下了伏笔。
分道扬镳
事实证明,指望一个全球最活跃的开源社区长期使用一个闭源工具似乎不太切合实际,毕竟这里聚集了一批全世界最有能力的程序员。于是,社区内开始出现“需要一个类BitKeeper的开源工具”的声音,甚至有实干者已经开始着手实现这件事情。
2005年,Linus本人所属公司OSDL的老板AndrewMorton资助的一个项目组开始对BitKeeper协议进行反向编译,试图破解BitKeeper以创造出一个类似的开源工具。BitMover公司很快发现了这一动作,Larry表示这破坏了免费版BitKeeper的许可协议,尽管这件事或许与Linus本人无关,但确实严重影响了公司的利益,他们最终决定逐步停止对免费版BitKeeper的支持,但会给Linux进行工具迭代的时间。
这样的矛盾在早期的商业公司与开源社区之间十分常见,由于此时与开源项目相关的商业模式并不成熟,很多像BitMover一样的商业软件公司选择站在开源社区的对立面,以保护自己赖以生存的传统商业模式。这些软件公司被业内称为保守派,尤其是以微软、Oracle、SAP等为首的大型软件开发商,他们坚持以付费的原则提供专有企业软件,凭借产品的技术壁垒收取高额的许可费。这样的商业模式不仅被追求开放自由的开源社区所唾弃,高昂的软件采购成本也让很多企业的IT采购人员头疼不已。
不过,BitMover的做法在当时来看确实也无可厚非,他们正当地维护了自己的合法权利,挽回了因产品被破解可能带来的经济损失。但令他们万万没有想到的是,开源社区强大的生产力可以成为他们发展的沃土,也能成为毁灭他们的武器。
用开源的方式创造Git
失去BitKeeper意味着Linux需要重新寻找一个分布式版本控制系统,Linus考察了当时所有的系统,却没有一个能够让他满意。
“于是他在邮件列表里发了一封邮件,说自己写了一些代码,准备作为在找到更好的版本管理系统之前的过渡系统。我觉得这似乎是件挺有意思的事情,于是就把代码下载了下来,看了一下发现只有1244行。”这是目前Git的主要维护者、Google工程师JunioCHamano(滨野纯)在一次采访中的描述。
是的,天才Linus只花了10天的时间,用C语言写了1244行代码,这就是如今火遍全球的分布式版本控制系统Git的雏形。Linus把写好的代码发到Linux社区的邮件列表里,并邀请社区里的开发者一起来完善它。“在一周时间内发生了很多事,不过归纳起来就是Linux的内核开发者们听说Linus要用个“新玩意”来管理代码,如果那个‘新玩意’太难用的话大家都痛苦,还不如一起想办法把这个东西做好用点。”Hamano就是收到邮件并首批参与Git项目的开发者之一。
据Hamano回忆,当时Linus考察了市面上所有的版本控制系统,没有一款让他满意的原因是它们都没有代码合并(merge)功能。“因为Linus只写C和Shell,而merge的逻辑实在太复杂,所以他多次发邮件到邮件列表,说要是有人能够用脚本语言实现一个就好了。不过谁也没有上钩。就这么过了一个星期,一直关注邮件列表的我用Perl把Linus过去多次提到的merge算法实现并投到了邮件列表里。这是我第一次有一定规模地向开源项目贡献代码。然而,尽管我详细地写了将近30个测试用例以及各种分支条件下应该怎么处理的表格,6个小时以后Linus提交到master分支的却是个截然不同的东西。据本人说是想到了更好的办法所以就这么着了。”
虽然听起来有些任性,但Linus给出的新方案确实让Hamano折服。
对于merge功能,BitKeeper的做法是在worktree里基本上只存放自己的文件,而merge不发生在这里。merge时首先会创建一个临时文件夹,在里面展开merge结果,发生冲突时就在里面解决,然后提交commit并在worktree里展开,这样就算merge完成了。这个方法很好地解决了协同开发常常遇到的代码冲突问题。类似于把发生冲突的两人关进一个小黑屋,“决出胜负”后的胜利者再进入worktree。
而Linus决定取消这个临时文件夹,直接在worktree上merge。具体来说,就是每次提交commit之前会生成记录本次提交内容的index,而这个index遵循“三步合并”原则,比如我们有一个共同的版本,你在这个版本的基础上做了一些变更,我在这个版本的基础上做了另一些变更,然后将这两个差分merge起来。那么把原始版本、我修改的版本、你修改的版本分别作为stage1,stage2,stage3依次添加到index里,merge就算完成了。例如最简单的情况,我和你都没有做出变更,那么merge的结果就是没有变更。如果我做了变更而你没有,那么最后得到的就是我变更以后的代码,反之亦然。另外还有一种特殊的情况,就是你和我都做了“相同”的变更。
开源本质上就是大家一起做一个项目,互相merge的过程。Git就是在这样的模式下诞生并日趋完善,成长为全球最主流的开源版本控制系统。而Linus做的事情只是花10天时间写了1244行代码,然后审查大家提交的merge。“虽然最早是我做了全部的编码和设计,但之后的维护都由Hamano来做,他把Git做得更接地气,让所有人都能使用。”Linus曾在Google进行的一次演讲中毫不吝啬地夸赞了社区的伙伴。
(图右为JunioCHamano)
作为开源项目的管理者,Linus不仅是个智商超群的编程天才,他的管理情商也很高。在维护一个开源项目时,对别人说“No”是家常便饭。当Linus拒绝别人的commit时,他总会在回复中强调“拒绝这个commit不是因为你的能力不行,而是这个commit不合适”,同时还会指出commit中的亮点并给予肯定,让对方觉得自己的工作没有白费,这样就不会打击贡献者的热情。“我那时候也是,Linus对我说,虽然你的提交没有采用,但测试用例还是能用的,针对现在的实现你稍微修正一下吧。”Hamano回忆说。
在Hamano等人的协助下,Git诞生近一个月后,Linux系统的源码就全部改用Git进行版本管理,而其他的开源项目社区也如获至宝,Git的名气很快就在开源界传播开来。
截然不同的命运
2008年,基于Git实现的代码托管平台GitHub面世,从此Git更是享誉全球。有意思的是,GitHub当初并不是由Git社区的人做的,而是出自Ruby社区的开发者之手,两个社区在最初的关系还有些不太和睦,原因是Git社区的人对于GitHub那群人拿Git去做商业化感觉很不爽……当然,这些都是老开发者口中的陈年往事了。毫无疑问,GitHub对于Git的普及做出了巨大的贡献。Hamano也表示:“有GitHub替我们做文档以及用户支持,何乐而不为呢。”
和Git的飞速发展形成鲜明对比的是,与Linux分道扬镳后的BitKeeper每况愈下,尽管后者是世界上首个商用级的分布式版本控制工具,但在Git诞生之后,BitKeeper的市场占有率断崖式下滑,几乎沦落到无人问津的地步。Git与BitKeeper的不同境遇可以说是21世纪初软件行业的缩影,传统的软件商业模式在开源浪潮的席卷下迎来了前所未有的挑战。
当然,挑战往往伴随着机遇。于是,也有一批人开始反思传统软件商业模式的局限性,试图寻找一种能够适应开源的全新商业模式。很快,以RedHat、MySQL、SugarCRM为代表的开源行业公司开始崛起,他们的商业模式是利用开源项目来推出增值服务,即免费向用户提供软件基础功能,而通过收费的增值服务来获取利益。
比如RedHat在RHEL推出的订阅服务,在用户免费使用这款企业级Linux系统的前提下,他们可以通过订阅,获得每一版本产品一定时间内的技术服务支持。这种支持包括但不限于系统升级、管理、维护;安全性和技术认证支持;其他硬件和软件支持。此外,RedHat还通过积极地投身开源社区为品牌赢得业内认可,从而促进其他收费产品的销售。自2001年确立商业模式以来,RedHat已经实现连续19个自然年的营收增长,创造了开源界的商业传奇。
当RedHat们利用开源项目取得前所未有的成功之后,许多传统软件开发商也开始意识到,开源已经是无法阻挡的时代趋势。2018年,曾经的“保守派”代表微软收购GitHub,进一步布局开源;2019年,蓝色巨人IBM斥资340亿美元收购RedHat,完成公司历史上最大规模的收购……越来越多的软件巨头参与到了开源社区的建设中,积极拥抱开源。
值得一提的是,2016年,在Git诞生11年之后,曾经与Linux短暂携手的BitKeeper宣布开源,只可惜为时已晚。