本文轉(zhuǎn)載自 InfoQ,作者 黃國峰
1 摘要
本文給大家剖析了一個有趣的現(xiàn)象:IT 業(yè)界使用最廣泛的版本管理系統(tǒng) Git,卻不被硅谷領(lǐng)先的科技公司 Google、Facebook 等垂青的原因。分析了 Google 的版本和分支管理模式、Git 的設(shè)計(jì)理念和存儲結(jié)構(gòu),為企業(yè) IT 的決策者提供一個版本管理系統(tǒng)技術(shù)選項(xiàng)的決策思路。
2 背景
版本控制系統(tǒng)(VCS,Version Control System),或叫源碼管理系統(tǒng)(SCM,Source Code Management)是幾乎所有 IT 人員都熟悉和每天工作使用的工具。提到 VCS,你會想到哪個工具?估計(jì)大部分人都會想到 Git,尤其對于 85 后年輕一代 IT 人,甚至可能只知道 Git 這一種版本管理工具。
Git 是目前最流行的代碼版本管理工具。它最初由 Linux 之父 Linus Torvalds 開發(fā)出來,Linus 2007 年在某次演講中提到他開發(fā) Git 的幾個準(zhǔn)則:
·分布式:代碼存儲在多個機(jī)器、每個副本是平等的、支持離線工作
·高性能:每次 commit、branch、log、diff 等操作都非常快
·可靠:確保從 Git 簽出(Checkout)的代碼跟簽入(Checkin)的代碼完全一致除了 Git,業(yè)界流行的版本控制系統(tǒng)還有 Subversion、Mercurial 等。
3 問題
Git 是一個非常適合開源社區(qū)的優(yōu)秀的版本管理系統(tǒng)。但包括 Google 和 Facebooke 等多個硅谷巨頭都沒有采用,微軟 Windows 開發(fā)團(tuán)隊(duì)雖然用 Git,但用的是經(jīng)過深度改造后的 Git。很奇怪,對不?
其實(shí),Google 公司并非完全沒有考慮過采用 Git,Linus 本人在 2007 年曾到 Google 公司進(jìn)行過一次介紹 Git 的演講,有興趣的朋友可以參考:Linus 在 2007 年 Google Talk 上介紹 Git。當(dāng)時 Google 采用一個商業(yè)軟件 Perforce 作為代碼版本管理工具,正為 Perforce 無法繼續(xù)支持 Google 巨大代碼倉庫而尋覓替代方案。但最終 Google 選擇了基于 Bigtable 自行研發(fā)版本管理工具 Piper,而沒有采用 Linus 大神開發(fā)的、名滿天下的 Git。
這到底是為什么呢?
4 答案
Git 并不比 Subversion 更好,它只是不同
首先,讓我們來看看 Git 是否(比其他流行的版本管理工具)更好,甚至最好。以 Git 市占率成為第 1 前最流行的 Subversion(簡稱 SVN)來對比。
在美版知乎網(wǎng)站 StackOverflow 上曾經(jīng)有一個問題《Why is Git better than Subversion?》,被采納的高贊回答是這樣說的:
Git is not better than Subversion. But is also not worse. It's different.
是的,只是 different。有哪些不同呢?從 Git 官網(wǎng)的介紹和 Subversion 官網(wǎng)的介紹可以看出來:

上表是 Git 和 Subversion 官網(wǎng)強(qiáng)調(diào)的幾個特性,我們來分析一下:
-
分布式和中心化,Git 和 Subversion 完全不同的思路;對于開源社區(qū)(比如 Linux),顯然分布式更合理,但對于商業(yè)公司,恐怕中心化更方便運(yùn)維和備份;2.Git 更強(qiáng)調(diào)低成本的分支(和合并),Subversong 也支持分支和合并,但更強(qiáng)調(diào)簡易的模型和易用性;3.Git 強(qiáng)調(diào)的是輕量和快(性能),而 Subversion 強(qiáng)調(diào)多用途(不僅僅是代碼,還支持二進(jìn)制文件)和規(guī)模; -
說法不同本質(zhì)一致,強(qiáng)調(diào)數(shù)據(jù)的可靠性;代碼是 IT 公司的核心資產(chǎn),可靠性怎么強(qiáng)調(diào)都不為過; -
都是開源和免費(fèi)的軟件;
Git 非常適合開源社區(qū)
開源社區(qū)的核心訴求是開放、自由、共創(chuàng),因此對版本管理系統(tǒng)的需求是:
-
開發(fā)者隨時都可以克隆和分叉任意一個代碼庫; -
開發(fā)者都可以在自己的分叉或分支上為所欲為; -
開發(fā)者可以按自己意愿把源碼存儲在任何機(jī)器上,不論是自己的 PC 還是 Github 服務(wù)器; -
開發(fā)者可以發(fā)起合并回原代碼庫的請求(Pull Request),而是否接受則由原項(xiàng)目所有者決定。因此,Linus 設(shè)計(jì)的 Git 非常強(qiáng)調(diào)分布式(Distributed),以滿足開源社區(qū)的代碼存儲自由;另外,極低成本的分支(branching)、分叉(fork)和合并(merge),滿足開源社區(qū)自由分叉代碼和合入的需求。
依托 Linus 本人的超級影響力,加上 Git 本身非常適合開源協(xié)作的特性,Git 幾乎成為開源社區(qū)唯一的代碼版本管理系統(tǒng)。
5 Git 并不特別適合企業(yè)
然而,Git 并不適合企業(yè),尤其是企業(yè)中大型的軟件系統(tǒng)。因?yàn)槠髽I(yè)對源代碼管理的訴求截然不同。源代碼作為 IT 企業(yè)或企業(yè)的 IT 部門最核心的資產(chǎn),管理需求是:
-
安全:包括代碼權(quán)限(代碼訪問權(quán)限可控)和數(shù)據(jù)安全(不丟失、一致性); -
易用性:簡單的代碼簽出(Check-out)、嵌入(Check-in)、分支、合并等操作; -
多種類的資源版本管理,包括源代碼,也包括資源文件(圖片、音樂、視頻、設(shè)計(jì)文件等); -
規(guī)模:支持?jǐn)?shù)百 GB 甚至 TB 級規(guī)模的代碼倉庫,設(shè)想一個數(shù)千人的開發(fā)團(tuán)隊(duì)超過 10 年代碼積累的大型軟件,這個規(guī)模的代碼倉庫是完全可能的。而這,恰恰就是 Google 為例的大型 IT 公司所需求的。Linus 2007 年在 Google 的演講中,2 名 Google 員工提出了 2 個問題: -
如果你有一個超級超級大的代碼庫(repository),想用 Git 來管理,還不能讓業(yè)務(wù)中斷 6 個月,你怎么做? -
使用 Git 怎么只 pull 代碼庫的其中一部分 path?Linus 大神沒有正面回答這 2 個問題。
事實(shí)是:Git 做不到。
Git 之所以無法存儲巨大的代碼庫,也無法 clone、pull、push 代碼庫文件樹的某個分支,是由其存儲結(jié)構(gòu)和設(shè)計(jì)理念所制約的,并不是簡單增加一個特性就可以解決的。這也是為什么 Google 員工 2007 年就向 Linus 提出這 2 個問題,但到今天為止,Git 仍然不能支持的根本原因。(后來版本的 Git 支持通過 filter 和 sparce checkout 只克隆 / 拉取某些目錄的代碼,但性能非常低)。
在 Git 對象模型里,所有對象都以 SHA-1 id 表述,包括 4 類對象:
1.blob:用于存儲文件數(shù)據(jù);
2.tree:可以理解為目錄,它指向其他目錄或 blob;
3.commit:一棵代碼樹的提交點(diǎn);
4.tag:標(biāo)記特別的提交(commit),通常用于標(biāo)記某次發(fā)布;
其中,tag 和 branch 只是指向 commit 的一個指針。Git 的核心存儲在于前 3 者。其結(jié)構(gòu)如下圖:

更詳細(xì)的 Git 存儲和訪問機(jī)制,超出本文的范疇,關(guān)注本公眾號,我將在未來分享。
6源碼管理系統(tǒng)的選型取決于研發(fā)流程
除了上面所述的考慮因素,源碼管理系統(tǒng)的選型最重要的還是取決于研發(fā)流程,尤其是分支和版本關(guān)聯(lián)
Google 的分支和版本管理原則包括:
-
基于充分測試的主干開發(fā):這意味著并不需要太多分支、代碼集中式存儲; -
基于大倉源碼的主干依賴:就是把所有的模塊和子工程都放在同一個代碼倉庫中,代碼間以源碼的主干版本為依賴,所以代碼倉庫會非常巨大。這 2 點(diǎn),都是 Git 無法滿足的。
綜上所述,Git 并不適合類似于 Google、Facebook 等采用單體代碼倉庫、主干開發(fā)模式的 IT 企業(yè)。因此,Google 于 2007 年自行開發(fā)了一套版本管理系統(tǒng) Piper??上?Google 并沒有開源出來。
最終結(jié)果:Google 在 2007 年前采用商業(yè)軟件 Perforce 作為其源碼管理系統(tǒng);2007 年后自行研發(fā) Piper 替代;Facebooke 則采用經(jīng)過深度改造的 Mercurial 系統(tǒng)。
Google 和 Facebook 這 2 個硅谷巨頭都沒有采用最留下的 Git 來管理源碼,根本原因在于其研發(fā)流程的核心:
-
主干開發(fā); -
基于大倉源碼的主干依賴;
7 總結(jié)
代碼版本管理系統(tǒng)的技術(shù)選項(xiàng),對于整個 DevOps 流程的效率和質(zhì)量有著重要的影響,而且一旦選定,往往遷移成本極大。作為企業(yè) IT 部門的決策者,務(wù)必非常審慎的做決策。建議至少從以下維度評估:
-
研發(fā)流程是主干開發(fā),還是分支開發(fā); -
代碼模塊之間(包括對公司內(nèi)部和第三方)的依賴,以制品(編譯后的 jar、so 等二進(jìn)制或字節(jié)碼包)還是源代碼形式; -
版本發(fā)布模式:主干發(fā)布、還是分支發(fā)布; -
代碼的開放程度:是企業(yè)全部開放,還是需要局部開發(fā); -
代碼的安全要求;經(jīng)過多維度的評估,能讓企業(yè) IT 的決策者作出更準(zhǔn)確的決策。
|