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