译者按:3月17日,Joel Spolsky在他影响了全球数百万程序员的著名博客Joel on Software中发表了最后一篇文章Distributed Version Control is here to stay, baby。特翻译这篇文章,以为纪念。另外,推荐他的博客文集《软件随想录》(More Joel on Software中文版)。

Joel Spolsky is the founder and CEO of Fog Creek Software in New York City.

前不久,杰夫、我,还有埃里克一块参加Stack Overflow Podcast的在线聊天。哥几个针对版本控制问题,狠狠地发了一通牢骚。特别是大批特批了以MercurialGit为代表的、新潮的DVCS(Distributed Version Control System,分布式版本控制系统)。

聊天中,我说:“我觉得,用它们来做分支和合并更简单,恰恰说明了你的同事可能会做更多的分支和合并。结果呢,就是你会把自己绕进去,最后非晕菜不可。”

说实话,你们也猜得到,参加那种聊天活动,不需要事先准备什么,不过是几个人东拉西扯地闲聊天而已。既然是闲聊天嘛,就免不了说错话,或者用技术术语来说就是——犯错误。要么哪句话里有错误,要么出发点有错误,要么就是出发点和话里都有错误。但这一次,我犯了一个低级错误。就像草莓配比萨、辣椒配面包,属于那种低级得不能再低级的错误。

在这次聊天之前,我们团队已经切换到Mercurial很长时间了,但这次切换真的把我搞晕了,我不得不花钱请人替我check in代码(开个玩笑)。不过,有一段日子我确实不好过,因为我得记住几个关键的命令,想象着自己是在Subversion中使用它们,期待能看到熟悉的结果。可是,一旦碰到结果跟我想象得不一样,我就会大惑不解。为此,我经常得颠儿颠儿地跑到楼下大房间里,请教本杰明或者雅各布。

你猜我的团队怎么说,“哎,乔总,这‘水银果汁’[注1]太神了,我们打算用实际的产品代码来测试一下它。另外,还有,这一点更重要,我们发现了一个大市场,我们可以为它提供有偿技术支持和托管服务。”(Mercurial是基于GPL的自由软件,但有不少公司在决定使用什么之前,总会需要某种支持。)

我心里想,你们问我,我问谁?你们都知道,我在公司并不真正作主,因为“管理的职能就是提供支持”嘛。然后,他们就把所有6名实习生都组织起来,动手开发基于Mercurial的产品

真不能再拖下去了,我必须得尽快弄明白,所谓的“分布式版本控制”到底咋回事。免得我们公司的产品都上市开卖了,人家让我介绍产品,我自己都说不出个子丑寅卯来。那样的话,博客圈里又会有人跳出来,对我指手画脚,说我糟蹋好东西了(junking the sharp)。

于是,我学呀,学呀,最后终于闹明白了。今天,我想跟大家在这里分享一下。

在分布式版本控制系统中,所谓的“分布式”其实不是最关键的。

最关键的是在使用这些系统时,你时刻要想着“更改”,而不是“版本”。

我明白,这里边其实有几分“道可道,非常道”的意味。在使用传统的版本控制系统时,你会想:嗯,这是版本1,这是版本2,这是版本3。

而在使用分布式版本控制系统时,其实我不用想版本。我只要想,我做了这些更改,我又做了另一些更改。

程序模型”变了,“用户模型”也得跟着变。

在Subversion中,你可能会想,“要保证我的版本跟主版本随时一致”,或者“恢复到前一个版本”。

在Mercurial中,你会这样想,“看看雅各布的更改”,或者“我们先不用考虑那些更改”。

如果你在使用Mercurial时,心里想的是Subversion,多数情况下倒也问题不大;但是,万一出了问题,你就会找不着北、会不高兴,最后因为无计可施而恨上Mercurial。

可是,如果你能够解放思想,换一个角度来看版本控制,就能悟出管理“版本”与管理“变更”的差异所在。你会觉得豁然开朗,由衷地感叹这才是控制版本的最佳方式。

没错,是有点异样的感觉——从1972年至今,所有人关注的都是怎么管理版本,而今天,人们突然要去关注更改本身了,能不感觉异样吗?而且,关注更改解决了一个非常重要的问题:合并分支代码。

这一点最重要了。没错,在长达10年的时间里,我们深刻地体会到,这一点对提高开发效率最为重要。重要到了什么程度呢?重要到在我今天最后一次谈软件时,必须要反复强调它。好了,如果你只想记住一句话,那就记住下面这句:

在管理更改而非管理版本时,合并很容易做到,你可以根据工作需要随时创建分支,因为合并已经是小菜一碟了。

记不清有多少个使用Subversion的用户,曾对我说过下面这番话:“用它创建分支代码的时候,没什么问题。但是,等到要把分支合并到一块时,那个费劲啊,我们不得不手工重新应用每一次更改。我们发誓,这种蠢事一辈子也不会再干了。结果,我们想出了一个开发软件的新主意,就是用if语句,不用分支。”

有时候,他们在提到自己发明的这种一个主干的做法时,甚至还有几分得意。好像弥补了自己版本控制工具的不足,就可以流芳百世了。

使用分布式版本控制系统,合并简单,还不会出错。所以,你可以创建一个稳定的分支、一个开发分支,还可以为QA团队创建一个长期使用的分支,以便在实际部署之前进行测试。当然,还可以创建一个临时分支,用它来验证各种想法,观察结果。

这一点太重要了,怎么强调它都不算过分。自从我10年前开始写博客以来,这恐怕是我笔下的软件开发技术领域中最大的进步了。

或者,可以换一种说法,如果我要放弃Mercurial,除非是我想再使用C++。

如果你还在使用Subversion,停止使用。马上停止使用。Subversion=水蛭。Mercurial=抗生素。我们现在有更好的技术了。

很多人在没有完全理解这种新程序模型的情况下,往往会盲目地使用Mercurial,而这容易让人觉得它有问题,不可靠。为此,我专门写了一套Mercurial教程,叫做HgInit[注2]

如今,要是有人问我那次聊DVCS时为什么要贬低DVCS,我会告诉他们那是我精心设计一个圈套,我是在放烟雾弹,目的是要迷惑我的老朋友和老竞争对手埃里克——他在开发一个非分布式的版本控制系统。就像上一次他要卖bug追踪软件一样。那一次,为了惩罚他,我们用一个特制的信封寄给他一个非常值钱的Fog Creek双肩背包。让他觉得我们会在圣诞节的时候,也会把这么值钱的背包作为圣诞礼物,送给所有FogBugz软件的客户。

我的博客写到今天,时间已经够长了。10年来,大家能够坚持阅读我写的文章,是我莫大的荣幸。这个博客的读者群能达到今天这个规模,是我当初做梦也想不到的。无论你是谁,是花自己的时间把我的文章翻译成40多种语言的那几百位志愿者中的一员,是给我写过电子邮件的22 894位朋友中的一位,是订阅了我的邮件简报的50 838名订阅者之一,还是每年2 262 384位访问这个站点并阅读了我写的1 067篇文章中哪怕只言片语的读者中的一位,我都要由衷地感谢你,感谢你对我的关注。