Git 15 週年:當年的分道揚鑣,成就了今天的開源傳奇
全球最主流的版本控制系統—— Git 迎來15週年紀念日,項目主要維護者Junio C Hamano(濱野純)先生髮郵件慶祝了這一日子。
我們知道,所有的軟件項目在整個生命週期中都要經過不斷迭代,在一個又一個的新版本中完善自己的功能。開源項目更是如此,一個健康的開源項目,在“集市”模式下接受來自世界各地開發者提交的代碼,版本更新頻率通常更高。如何管理項目的版本更新,是項目開發、維護過程中必須考慮的問題。
什麼是版本控制工具
在開始我們的故事之前,首先讓我們來認識一下版本控制工具。版本控制的核心述求是歷史紀錄查詢和實現協同開發。以開源項目來說,在多人協作開發的模式下,每個人都向服務器提交自己的文件,就可能存在著代碼被多次修改、替換的風險,但是版本控制能夠在每次更新操作後進行相應的記錄。一旦發生誤操作,開發者能夠根據服務器中的版本記錄,將項目恢復到出現問題之前的其他版本。因此,借助版本控制技術,軟件開發項目可以被分割為若干模塊,每個模塊並行地進行開發工作,從而有效地提高了整體編程效率。
主流的版本控制工具主要分為兩種,即集中式與分佈式。
集中式版本控制工具類似網吧的管理系統,所有項目的歷史文件與版本信息都存放在服務器上,而客戶端就只能保存當前的狀態信息。這種所有雞蛋裝在一個籃子裡的模式缺點非常明顯,一旦服務器損壞,項目所有的歷史數據就會丟失,因此需要大規模的安全備份。比較有代表性的集中式版本控制工具有SVN、VSS、CVS等。
分佈式版本控制工具最大的特性就是任意客戶端之間可以互聯,當然也包括服務器。這樣一來,開發者的客戶端本地也存有項目完整的歷史記錄,當有一個客戶端損壞時,可以從另一個沒有被損壞的客戶端中提取歷史數據,恢復之前的狀態。在協同開發時,各個客戶端之間可以很好地同步開發進度,避免出現重複提交等問題。
毫無疑問,分佈式版本控制工具擁有更為先進的理念,其誕生的過程也是得益於網絡通信技術的普及與開源社區的蓬勃發展。
天才的幫手
我們的故事始於1991 年,大名鼎鼎的開源項目Linux 問世,作者Linus Torvalds 一躍成為IT 界的大明星,被人們稱為天才。由於當時Linux 社區仍採用傳統的集中式版本管理,開發者提交的patch 都匯集到Linus 這裡,讓他肩上的擔子很重。
( Linus Torvalds )
在項目早期,Linus 以最原始的人力來完成Linux 版本管理工作,包括逐條細看每個patch、手動合併開發者提交的代碼、更新版本歷史信息等。由於這段“痛苦”的經歷,Linus 本人曾多次公開吐槽“代碼管理是計算機領域最無趣的事”……
然而隨著社區的逐漸壯大,Linux 的系統變得越來越龐大,代碼越來越繁雜,繼續依靠手動合併代碼顯然已經不太現實。
1999年,一家名為BitMover的公司發布了一款收費的分佈式版本控制軟件BitKeeper,BitMover的CEO Larry給Linux社區特別提供了一個可以免費使用的版本,期望BitKeeper能幫助Linus免於陷入不斷加重的Linux內核管理工作中,但條件是不能破解這款產品。
Linus 在使用BitKeeper 之後不久就愛上了它,直言其是“ Best tool for the job ”。BitKeeper 讓每個開發者都擁有自己的主副本( master copy ),完整的副本意味著可以在本地做所有事,而不是所有的patch 只能提交到服務器(Linus)這裡。於是,Linus 可以把一些patch 的審查工作交給Liunx 子系統的維護者們,對於比較值得信任的維護者甚至不需要他自己再審查一遍,而他只需要對一些自己不太信任的維護者“重點關照” 即可。2002 年,Linux 內核主線代碼就全面開始使用BitKeeper。
儘管BitKeeper 的出現賦予了Linux 社區更好的協同開發能力,讓Linux 內核的開發效率成倍提高,但其閉源的特性仍然讓Linus 在開源界遭到了一些非議。開源泰斗RSM 就嚴厲批評Linus 不該使用一款非自由的軟件來管理世界上最大的開源項目。這些負面的聲音也為之後Linux 與BitKeeper 的分道揚鑣埋下了伏筆。
分道揚鑣
事實證明,指望一個全球最活躍的開源社區長期使用一個閉源工具似乎不太切合實際,畢竟這裡聚集了一批全世界最有能力的程序員。於是,社區內開始出現“需要一個類BitKeeper 的開源工具”的聲音,甚至有實幹者已經開始著手實現這件事情。
2005年,Linus本人所屬公司OSDL的老闆Andrew Morton資助的一個項目組開始對BitKeeper協議進行反向編譯,試圖破解BitKeeper以創造出一個類似的開源工具。BitMover公司很快發現了這一動作,Larry表示這破壞了免費版BitKeeper的許可協議,儘管這件事或許與Linus本人無關,但確實嚴重影響了公司的利益,他們最終決定逐步停止對免費版BitKeeper的支持,但會給Linux進行工具迭代的時間。
這樣的矛盾在早期的商業公司與開源社區之間十分常見,由於此時與開源項目相關的商業模式並不成熟,很多像BitMover一樣的商業軟件公司選擇站在開源社區的對立面,以保護自己賴以生存的傳統商業模式。這些軟件公司被業內稱為保守派,尤其是以微軟、Oracle、SAP等為首的大型軟件開發商,他們堅持以付費的原則提供專有企業軟件,憑藉產品的技術壁壘收取高額的許可費。這樣的商業模式不僅被追求開放自由的開源社區所唾棄,高昂的軟件採購成本也讓很多企業的IT採購人員頭疼不已。
不過,BitMover 的做法在當時來看確實也無可厚非,他們正當地維護了自己的合法權利,挽回了因產品被破解可能帶來的經濟損失。但令他們萬萬沒有想到的是,開源社區強大的生產力可以成為他們發展的沃土,也能成為毀滅他們的武器。
用開源的方式創造Git
失去BitKeeper 意味著Linux 需要重新尋找一個分佈式版本控制系統,Linus 考察了當時所有的系統,卻沒有一個能夠讓他滿意。
“ 於是他在郵件列表裡發了一封郵件,說自己寫了一些代碼,準備作為在找到更好的版本管理系統之前的過渡系統。我覺得這似乎是件挺有意思的事情,於是就把代碼下載了下來,看了一下發現只有1244行。” 這是目前Git 的主要維護者、Google 工程師Junio C Hamano(濱野純)在一次採訪中的描述。
是的,天才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 的做法是在work tree 里基本上只存放自己的文件,而merge 不發生在這裡。merge 時首先會創建一個臨時文件夾,在裡面展開merge 結果,發生衝突時就在裡面解決,然後提交commit 並在work tree 裡展開,這樣就算merge 完成了。這個方法很好地解決了協同開發常常遇到的代碼衝突問題。類似於把發生衝突的兩人關進一個小黑屋,“決出勝負”後的勝利者再進入work tree 。
而Linus 決定取消這個臨時文件夾,直接在work tree 上merge 。具體來說,就是每次提交commit 之前會生成記錄本次提交內容的index,而這個index 遵循“三步合併”原則,比如我們有一個共同的版本,你在這個版本的基礎上做了一些變更,我在這個版本的基礎上做了另一些變更,然後將這兩個差分merge 起來。那麼把原始版本、我修改的版本、你修改的版本分別作為stage1,stage2,stage3 依次添加到index 裡,merge 就算完成了。例如最簡單的情況,我和你都沒有做出變更,那麼merge 的結果就是沒有變更。如果我做了變更而你沒有,那麼最後得到的就是我變更以後的代碼,反之亦然。另外還有一種特殊的情況,就是你和我都做了“相同”的變更。
開源本質上就是大家一起做一個項目,互相merge的過程。Git就是在這樣的模式下誕生並日趨完善,成長為全球最主流的開源版本控制系統。而Linus做的事情只是花10天時間寫了1244行代碼,然後審查大家提交的merge 。“ 雖然最早是我做了全部的編碼和設計,但之後的維護都由Hamano來做,他把Git做得更接地氣,讓所有人都能使用。” Linus曾在Google進行的一次演講中毫不吝嗇地誇讚了社區的伙伴。
(圖右為Junio C Hamano)
作為開源項目的管理者,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世紀初軟件行業的縮影,傳統的軟件商業模式在開源浪潮的席捲下迎來了前所未有的挑戰。
當然,挑戰往往伴隨著機遇。於是,也有一批人開始反思傳統軟件商業模式的局限性,試圖尋找一種能夠適應開源的全新商業模式。很快,以Red Hat、MySQL、SugarCRM 為代表的開源行業公司開始崛起,他們的商業模式是利用開源項目來推出增值服務,即免費向用戶提供軟件基礎功能,而通過收費的增值服務來獲取利益。
比如Red Hat 在RHEL 推出的訂閱服務,在用戶免費使用這款企業級Linux 系統的前提下,他們可以通過訂閱,獲得每一版本產品一定時間內的技術服務支持。這種支持包括但不限於系統升級、管理、維護;安全性和技術認證支持;其他硬件和軟件支持。此外,Red Hat 還通過積極地投身開源社區為品牌贏得業內認可,從而促進其他收費產品的銷售。自2001 年確立商業模式以來,Red Hat 已經實現連續19 個自然年的營收增長,創造了開源界的商業傳奇。
當Red Hat們利用開源項目取得前所未有的成功之後,許多傳統軟件開發商也開始意識到,開源已經是無法阻擋的時代趨勢。2018年,曾經的“保守派”代表微軟收購GitHub,進一步佈局開源;2019年,藍色巨人IBM斥資340億美元收購Red Hat,完成公司歷史上最大規模的收購……越來越多的軟件巨頭參與到了開源社區的建設中,積極擁抱開源。
值得一提的是,2016年,在Git誕生11年之後,曾經與Linux短暫攜手的BitKeeper宣布開源,只可惜為時已晚。