Google 和 Facebook 爲什麼不用 Git 管理源碼?

1 摘要

本文給大家剖析了一個有趣的現象:IT 業界使用最廣泛的版本管理系統 Git,卻不被硅谷領先的科技公司 Google、Facebook 等垂青的原因。分析了 Google 的版本和分支管理模式、Git 的設計理念和存儲結構,爲企業 IT 的決策者提供一個版本管理系統技術選項的決策思路。

2 背景

版本控制系統(VCS,Version Control System),或叫源碼管理系統(SCM,Source Code Management)是幾乎所有 IT 人員都熟悉和每天工作使用的工具。提到 VCS,你會想到哪個工具?估計大部分人都會想到 Git,尤其對於 85 後年輕一代 IT 人,甚至可能只知道 Git 這一種版本管理工具。

Git 是目前最流行的代碼版本管理工具。它最初由 Linux 之父 Linus Torvalds 開發出來,Linus 2007 年在某次演講中提到他開發 Git 的幾個準則:

• 分佈式:代碼存儲在多個機器、每個副本是平等的、支持離線工作

• 高性能:每次 commit、branch、log、diff 等操作都非常快

• 可靠:確保從 Git 簽出(Checkout)的代碼跟簽入(Checkin)的代碼完全一致除了 Git,業界流行的版本控制系統還有 Subversion、Mercurial 等。

3 問題

Git 是一個非常適合開源社區的優秀的版本管理系統。但包括 Google 和 Facebooke 等多個硅谷巨頭都沒有采用,微軟 Windows 開發團隊雖然用 Git,但用的是經過深度改造後的 Git。很奇怪,對不?

其實,Google 公司並非完全沒有考慮過採用 Git,Linus 本人在 2007 年曾到 Google 公司進行過一次介紹 Git 的演講,有興趣的朋友可以參考:Linus 在 2007 年 Google Talk 上介紹 Git。當時 Google 採用一個商業軟件 Perforce 作爲代碼版本管理工具,正爲 Perforce 無法繼續支持 Google 巨大代碼倉庫而尋覓替代方案。但最終 Google 選擇了基於 Bigtable 自行研發版本管理工具 Piper,而沒有采用 Linus 大神開發的、名滿天下的 Git。

這到底是爲什麼呢?

4 答案

Git 並不比 Subversion 更好,它只是不同

首先,讓我們來看看 Git 是否(比其他流行的版本管理工具)更好,甚至最好。以 Git 市佔率成爲第 1 前最流行的 Subversion(簡稱 SVN)來對比。

在美版知乎網站 StackOverflow 上曾經有一個問題《Why is Git better than Subversion?》,被採納的高贊回答是這樣說的:

Git is not better than Subversion. But is also not worse. It's different.

是的,只是 different。有哪些不同呢?從 Git 官網的介紹和 Subversion 官網的介紹可以看出來:

上表是 Git 和 Subversion 官網強調的幾個特性,我們來分析一下:

  1. 分佈式和中心化,Git 和 Subversion 完全不同的思路;對於開源社區(比如 Linux),顯然分佈式更合理,但對於商業公司,恐怕中心化更方便運維和備份;2.Git 更強調低成本的分支(和合並),Subversong 也支持分支和合並,但更強調簡易的模型和易用性;3.Git 強調的是輕量和快(性能),而 Subversion 強調多用途(不僅僅是代碼,還支持二進制文件)和規模;

  2. 說法不同本質一致,強調數據的可靠性;代碼是 IT 公司的核心資產,可靠性怎麼強調都不爲過;

  3. 都是開源和免費的軟件;

Git 非常適合開源社區

開源社區的核心訴求是開放、自由、共創,因此對版本管理系統的需求是:

  1. 開發者隨時都可以克隆和分叉任意一個代碼庫;

  2. 開發者都可以在自己的分叉或分支上爲所欲爲;

  3. 開發者可以按自己意願把源碼存儲在任何機器上,不論是自己的 PC 還是 Github 服務器;

  4. 開發者可以發起合併回原代碼庫的請求(Pull Request),而是否接受則由原項目所有者決定。因此,Linus 設計的 Git 非常強調分佈式(Distributed),以滿足開源社區的代碼存儲自由;另外,極低成本的分支(branching)、分叉(fork)和合並(merge),滿足開源社區自由分叉代碼和合入的需求。

依託 Linus 本人的超級影響力,加上 Git 本身非常適合開源協作的特性,Git 幾乎成爲開源社區唯一的代碼版本管理系統。

5Git 並不特別適合企業

然而,Git 並不適合企業,尤其是企業中大型的軟件系統。因爲企業對源代碼管理的訴求截然不同。源代碼作爲 IT 企業或企業的 IT 部門最核心的資產,管理需求是:

  1. 安全:包括代碼權限(代碼訪問權限可控)和數據安全(不丟失、一致性);

  2. 易用性:簡單的代碼簽出(Check-out)、嵌入(Check-in)、分支、合併等操作;

  3. 多種類的資源版本管理,包括源代碼,也包括資源文件(圖片、音樂、視頻、設計文件等);

  4. 規模:支持數百 GB 甚至 TB 級規模的代碼倉庫,設想一個數千人的開發團隊超過 10 年代碼積累的大型軟件,這個規模的代碼倉庫是完全可能的。而這,恰恰就是 Google 爲例的大型 IT 公司所需求的。Linus 2007 年在 Google 的演講中,2 名 Google 員工提出了 2 個問題:

  5. 如果你有一個超級超級大的代碼庫(repository),想用 Git 來管理,還不能讓業務中斷 6 個月,你怎麼做?

  6. 使用 Git 怎麼只 pull 代碼庫的其中一部分 path?Linus 大神沒有正面回答這 2 個問題。

事實是:Git 做不到。

Git 之所以無法存儲巨大的代碼庫,也無法 clone、pull、push 代碼庫文件樹的某個分支,是由其存儲結構和設計理念所制約的,並不是簡單增加一個特性就可以解決的。這也是爲什麼 Google 員工 2007 年就向 Linus 提出這 2 個問題,但到今天爲止,Git 仍然不能支持的根本原因。(後來版本的 Git 支持通過 filter 和 sparce checkout 只克隆 / 拉取某些目錄的代碼,但性能非常低)。

在 Git 對象模型裏,所有對象都以 SHA-1 id 表述,包括 4 類對象:

1.blob:用於存儲文件數據;

2.tree:可以理解爲目錄,它指向其他目錄或 blob;

3.commit:一棵代碼樹的提交點;

4.tag:標記特別的提交(commit),通常用於標記某次發佈;

其中,tag 和 branch 只是指向 commit 的一個指針。Git 的核心存儲在於前 3 者。其結構如下圖:

更詳細的 Git 存儲和訪問機制,超出本文的範疇,關注本公衆號,我將在未來分享。

6 源碼管理系統的選型取決於研發流程

除了上面所述的考慮因素,源碼管理系統的選型最重要的還是取決於研發流程,尤其是分支和版本關聯

Google 的分支和版本管理原則包括:

  1. 基於充分測試的主幹開發:這意味着並不需要太多分支、代碼集中式存儲;

  2. 基於大倉源碼的主幹依賴:就是把所有的模塊和子工程都放在同一個代碼倉庫中,代碼間以源碼的主幹版本爲依賴,所以代碼倉庫會非常巨大。這 2 點,都是 Git 無法滿足的。

綜上所述,Git 並不適合類似於 Google、Facebook 等採用單體代碼倉庫、主幹開發模式的 IT 企業。因此,Google 於 2007 年自行開發了一套版本管理系統 Piper。可惜 Google 並沒有開源出來。

最終結果:Google 在 2007 年前採用商業軟件 Perforce 作爲其源碼管理系統;2007 年後自行研發 Piper 替代;Facebooke 則採用經過深度改造的 Mercurial 系統。

Google 和 Facebook 這 2 個硅谷巨頭都沒有采用最留下的 Git 來管理源碼,根本原因在於其研發流程的核心:

  1. 主幹開發;

  2. 基於大倉源碼的主幹依賴;

7 總結

代碼版本管理系統的技術選項,對於整個 DevOps 流程的效率和質量有着重要的影響,而且一旦選定,往往遷移成本極大。作爲企業 IT 部門的決策者,務必非常審慎的做決策。建議至少從以下維度評估:

  1. 研發流程是主幹開發,還是分支開發;

  2. 代碼模塊之間(包括對公司內部和第三方)的依賴,以製品(編譯後的 jar、so 等二進制或字節碼包)還是源代碼形式;

  3. 版本發佈模式:主幹發佈、還是分支發佈;

  4. 代碼的開放程度:是企業全部開放,還是需要局部開發;

  5. 代碼的安全要求;經過多維度的評估,能讓企業 IT 的決策者作出更準確的決策。

8 後記

上文中,我們提到 Google 分支和版本管理的 2 個原則:主幹開發、大倉源碼的主幹依賴。這 2 點都跟國內業界大部分公司不同,讀者可能會很疑慮。對於第 1 點,可以參考本公衆號的文章《Google 工程效能三板斧之 單體代碼倉庫》。對於第 2 點,請期待後續分享。


本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。