Linus Torvalds 曾写了一本书提到,当初创造 Linux 只是因为好玩,却意外掀起一场
革命。Git 是 Linus 的第二代表作,同样也是意外的革命,是现在软件工程师的标配,
但至少对 Linus 本人来说,它的起源可就没这么好玩了。
图文完整版:https://blog.brachiosoft.com/posts/git/
脸书专页:https://www.facebook.com/brachiosoft
# Linus 扩展不了
1998 年是 Linux 风光的一年,许多大公司,如升阳、IBM 和甲骨文,都纷纷投入 Linux
的业务。那年春天,Linus 的二女儿出生,他们一家从芬兰搬到美国加州也差不多一年
,生活步入正轨。虽然 Linux 还尚未给 Linus 带来什么收益,但 Linus 也可算是事业
家庭两得意。
反观 Linux Kernel 的开发者社群,随着愈来愈多人加入开发,既有的合作方式开始力
不从心。Linus 开始显得没办法跟上开发者们修改程式码的速度,逐渐成为瓶颈。
1998 年 9 月 28 日,Linus 和往常一样,读著 Linux Kernel 邮件列表上的信。
> 请不要浪费时间送修补了,这些在 vger 上早就修好了。
Linus 看到这句话不太高兴。一直以来,Linux 程式码的修改重度仰赖 Linus 本人,
Linus 本人就是版本控管。如果你要修改程式码,寄封信到邮件列表上,Linus 看到了
并认可,就会将你的修补送进他自己的版本,然后不时在 FTP 上释出新版本。Linus 喜
欢这样的合作方式,因为他可以掌控一切变更,大家也信任 Linus,觉得 Linux 本来就
该由 Linus 掌控。
但自从 David Miller,一位 Linux Kernel 的资深开发者,架设了一个名为 vger 的
CVS 服务器,有些人就以为可以绕过 Linus 本人,将变更送到 vger 就没事了。这不是
Linus 第一次遇到同样的问题,他在邮件列表上不悦的回应:
> “在 vger 上就不要浪费时间”这个说法完全是愚蠢的,因为 vger 上很多东西可能
> 永远都不会进 2.2。
于是几个开发者与 Linus 展开一场激烈的笔战,他们开始陈情,说 Linus 回信太慢,
甚至有时候要寄三次才会得到这个“仁慈独裁者”的亲回。
“这些家伙也不照照镜子,”Linus 心想:“我一天要看多少信,如果连寄三次信都嫌
麻烦,那这个修补我宁可不要。” Linus 在讨论串留下这个讯息随即怒离:
> 这次的讨论只是让我烦燥,增加我的压力。走开吧,不要再 CC 我了,我要度假去了
> ,我不要再听到任何有关它的事。总之,滚出我的信箱就对了。
Linus 情绪性的发言反而让一些人开始提出正面的帮助。
开源运动代表人物之一 Eric S. Raymond,著名文章《大教堂和市集》就是他写的。看
到 Linus 的怒离文,他冷静地呼吁:
> 各位,这些是职业倦怠的早期征兆。Linus 一直以来的毅心确实令人敬佩,但他也是
> 有极限的。我们所有人(是的,也包括你 Linus)要一起想办法帮这个重要人物减少
> 压力,而不是增加压力。
另一位伸出援手的是 Larry McVoy,在一篇标题为“成长痛的解决方案”的邮件,他这
么写:
> 问题症结在于 Linus 扩展不了("Linus doesn’t scale")。我们不能期待 Linus 一
> 个人能跟上 Kernel 变化的速度,我们也不想看到 Linus 失去对 Kernel 的掌控,他
> 已一再证明自己非常适任此职。
>
> (解决方案基本上是)将工作分担给 Linus 身边的几个人,要做到分担,我们要导入
> 新工具。
> (这个新工具是)一个分布式版本控管系统...
Larry 当时正好在开发一套新的版控软件,叫做 BitKeeper。
# BitKeeper 的起源
在 1990 年代早期,升阳导入了一套名为 Network Software Environment (NSE) 的内
部工具来管理程式码,但 NSE 太慢了,使用体验极差,有些工程师甚至为此愤而离职。
Larry McVoy 不仅是个资深的作业系统开发者,过去也做过许多效能相关的工作,所以
升阳的主管就找上了 Larry 来调教一下 NSE 的效能。
Larry 一看 NSE 的程式码吓了一跳,“这东西很多地方当初设计时都没有考量到效能。
”他还发现 NSE 的底层其实是 SCCS,SCCS 是 1970 年代的版本控管软件,出现比 CVS
和 Subversion 还早。与其修改体质不良 NSE,Larry 选了另一条路:他用 Perl 写了
NSElite,在 SCCS 之上实作了 resync/resolve 指令,基本上类似现今 Git 的
clone/pull/push 指令。
NSElite 比 NSE 快多了,所以升阳的工程师一个一个背弃 NSE,改用 NSElite。升阳某
VP 见状,觉得有商机,就组了一个八人团队,想要用 C++ 重写 Larry 写的 Perl 脚本
,将其产品化为 TeamWare。
TeamWare 大概是最早的分布式版控系统,后来升阳 Solaris 作业系统的开发全是借助
于它。工程师们用过 TeamWare 都表示回不去了:不同于 CVS 和 Subversion,TeamWare
让你将整个专案复制到你自己的机器,你可以尽情地在本地端提交变更,等到准备好再
将你自己本地的版本合并回远端版本。
这八人团队的成员本来是写 C 语言的,当时 C++ 是新的火热语言,他们边学 C++ 边开
发 TeamWare。在 TeamWare 还未完成前,Larry 曾尝试继续开发 NSElite,但这无疑是
给 TeamWare 团队难堪:一个人用 Perl 竟然比八个人用 C++ 还来得快,VP 见状便告诉
Larry:“这件事已经上报给 Scooter(即 Scott McNealy,升阳的执行长),如果你再
发布一次,你就被解雇了。”
为此,1991 年,Larry 停止 NSElite 的开发,但建造一个分布式版控软件的念头始终
在他心中挥之不去。他本来以为会有其他商用软件会跟进 TeamWare 的脚步,但并没有
。1997 年 Larry 开始着手开发一款名为 BitKeeper 的分布式版控软件。然而,直到
1998 年 9 月,当他看到邮件列表上 Linus 处于崩溃边缘,这才真正激励他开始认真看
待 BitKeeper 这个专案。
# Linux Kernel 采用 BitKeeper
1998 年秋天某日,Larry 邀请了 Linus Torvalds、David Miller、Richard Henderson
来家中,吃完晚餐后,他们席地而坐,开始协商对策要如何减少 Linus 的工作量。他们
在地板画了三、四个小时的图,这些图大致上就是 TeamWare 在升阳内部行之有年的运
作方式,Larry 对此十分熟悉。
在这个框架中,开发者们可利用 BitKeeper 各自开发,不互相干扰,而且在 Linus 这
边做最后整合时,能够不失去修改的历史记录,让 Linus 能看出一个变更的来龙去脉,
审查程式码时更容易。
“好吧,如果你做出来,而且跑起来跟你说的一样,我就会用它。”Linus 说道。
“没问题,这我以前做过,大概需要六个月。”Larry 回答。
Larry 马上就意识到他低估了问题的复杂度,所以他成立了一间名为 BitMover 公司,
找了几个熟悉版控系统的好手,一起打造 BitKeeper。19 个月后,2000 年 5 月,
BitKeeper 公开释出第一版,此时 BitMover 是一个七人团队。
第一版的 BitKeeper 有一个命令列工具 bk,也有一些图形接口的工具。其中
bk clone/pull/push 命令作用有犹如 git clone/pull/push。
当时升阳的 TeamWare 已是有口皆碑,而 BitKeeper 更是 TeamWare 的强化版。例如,
TeamWare 只允许在 NFS 档案系统间传递资料,而 BitKeeper 可以走 HTTP 来传输档案
,实现了真正的分散。因此不久后,BitKeeper 就为 BitMover 带来充沛的现金流,到了
2002 年,BitMover 团队成长到了 25 人,完全自给自足,没靠外部资金。
2002 年 1 月,Linus 工作量太大的问题又再度浮现,开发者送出的修补不是等很久才
迟迟回应,不然就是被忽略。有人写了一篇“小小的提议”尝试改善这个问题。讨论串
中,有人随口提到“bitkeeper 真是个好工具”,唤醒了三年前,Larry 家中的那顿晚
餐,在 Linus 脑中种下的那颗种子。Linus 问道:“有多少人在用 bitkeeper 做
kernel 开发?”
果不其然,当时已经有些 Kernel 开发者早就在使用 BitKeeper。Linux PowerPC (PPC)
团队早在 1999 年 12 月就开始试用 BitKeeper,BitMover 为了帮助他们,架设了
bkbits.net 服务器。
过没几天,2002 年 2 月 5 日,邮件列表上就看到 Linus 开始在测试 BitKeeper。此
后,Linux Kernel 主要开发者们也跟进开始采用 BitKeeper。你不一定要用 BitKeeper
才能参与开发,但如果你是 BitKeeper 的使用者,流程大概是:
# 下载仓储(repository)
bk clone bk://linux.bkbits.net/linux-2.5 linux-2.5
bk clone linux-2.5 alpha-2.5
# 从另一个地方下载变更
cd alpha-2.5
bk pull bk://gkernel.bkbits.net/alpha-2.5
# 编辑档案并将变更上传回远端
bk vi fs/inode.c
bk push bk://[email protected]/alpha-2.5
若要将变更送给 Linus,你就再寄封信到邮件列表上,内容大致是:
Here is an update for something something...
Please pull from: bk://gkernel.bkbits.net/alpha-2.5
example/file1.c | 6 ++++++
example/file2.c | 4