引子:知乎問題?php
代碼版本控制用SVN仍是Git好? SVN和Git都有分支,如今須要對代碼進行版本控制,都各有什麼優缺點?二者都有用過,可是僅限於會使用,更多的利弊仍是不太瞭解。公司對目錄權限訪問控制要求嚴格,員工以前一直用的SVN。如今是打算都用git
-------------------------------------------------------------------------------------------------------程序員
介紹這個話題,有兩個緣由:服務器
- 從開始工做到如今,我經歷過沒有代碼版本管理、代碼集中式管理,以及如今的分佈式管理,我深入體會到它在軟件開發過程當中的重要性;
- 我在工做中遇到的不少客戶都存在對於代碼版本管理的各類問題、困惑和不一樣的需求。
因此我但願將我在這個方面的經驗分享給更多人,但願能幫助更多的團隊解決在代碼版本控制方面的問題和疑惑。網絡
(圖片來自:http://t.cn/RSPnA5t)分佈式
1、代碼版本管理系統的歷史
代碼版本管理系統大體能夠分爲三個時代:svn
第一代:本地式工具
這代主要的特色提供本地代碼版本控制,好比SCCS(1972)、 PVCS(1985)等。學習
這代主要實現了基本的代碼版本管理,但缺點是沒法讓多人同時對一個版本庫進行修改。這個也和當時軟件規模不夠大有關,也沒有這樣的需求。測試
第二代:客戶端-服務器式
這代主要的特色是提供集中式服務器端代碼版本控制,好比 CVS(1986), ClearCase(1992), Visual SourceSafe(1994), Perforce(1995), Subversion(2000) 等。
這代主要是實現了中心服務器端的代碼版本管理,特色是可讓多人同時對一個代碼版本庫進行同步和修改,但缺點也至關明顯:
- 在沒法鏈接服務器的狀況下,沒法查看日誌以及提交和比較代碼版本(慢速網絡和遠程異地工做的程序員的痛),以及當服務或者網絡出現問題的時候不少人員就會沒法工做。
- 不支持local branch,致使branch建立管理複雜,而且一旦建立就很難修改(快速迭代開發中的程序員的痛)
- 因爲只有一箇中心端服務器,一旦發生災難性問題,那麼全部日誌都會丟失,因此須要常常作備份(備份須要不小的成本)
- 若是軟件代碼量過於龐大,通常會出現速度緩慢的狀況,由於每次的日誌查詢、不一樣版本之間的代碼比較和代碼提交等操做都須要和服務器通訊,形成服務器端的負載過大。
第三代:分佈式
這代主要的特色是提供分佈式代碼版本控制,好比Git(2005), Mercurial(2005)等。
這代結合了第一代和第二代的優勢並實現了分佈式的代碼版本管理。
這代的優勢:分佈式管理,在沒有和服務器有鏈接的狀況下仍然能夠查看日誌,提交代碼,建立分支;支持local branch,能夠快速方便的實現各類分支管理;支持分佈式,從而能夠實現分塊管理,以及負載分流管理。
缺點是有必定的學習曲線,好比分佈方式下的代碼同步,local branch的理解與運用,分佈式代碼管理的理解與運用等。詳細的比較能夠參考:這裏。
2、大型分佈式團隊
曾經有這樣一個分佈式團隊,他們在多個城市都有小分隊,而且正在開發一個大型項目,見下圖
他們使用的代碼版本管理工具是第二代代碼管理工具SVN,管理方案以下:
可是他們在使用的過程當中卻遇到了下面這些問題與痛點。
因爲是分佈式團隊,因此:
- 基於團隊的代碼模塊分離困難
當服務器不可用時:
- 不能查看提交記錄
- 不能比較文件
- 不能提交代碼
建立代碼分支時:
- 分支建立速度慢
- 多分支管理困難
在提交代碼時:
- 但願有Code Review
- 但願有CI Review
由於代碼龐大:
- 查看日誌慢
備份代碼庫的時候:
- 須要停機備份
- 備份成本高
針對以上問題,可使用新一代的分佈式的代碼版本管理系統來解決,見下圖:
其中每個團隊都有本身獨立的代碼庫,有一箇中心庫用於同步這些獨立的代碼庫,而且每一個庫都由團隊本身管理和維護。並且代碼版本管理系統須要支持輕量分支,代碼評審,離線提交,離線查看日誌等功能。
可是因爲當前沒有一個單一的代碼版本管理工具能同時知足以上全部需求,因此不少公司都基於它們開發集成管理系統,好比Gerrit,GitLab,GitHub,BitBucket等。其中的Gerrit因爲其開源,免費,以及由Google開發和維護,並管理着Android,OpenStack等大型項目源代碼的特色,成爲了大型分佈式團隊優先選擇的系統。
3、Gerrit
Gerrit是由Google開發的,用於管理Google Android項目源代碼的一個系統。它是基於Java和Prolog等開發的,支持Git,權限管理,代碼評審等綜合的一個管理系統。它與GitLab和GitHub最大的不一樣是它隱藏了代碼分庫管理的細節,使得開發人員不須要進行fork這樣的手工分庫和同步操做就能夠進行代碼開發和提交,節省了開發人員的時間,見下圖。
因爲Android自己是一個開源項目,因此貢獻者很是多,開發團隊也遍及多個地方(存在時差),致使「如何保證代碼質量」成爲一個很大的問題。爲此Google在Gerrit中加入了功能強大而且十分嚴格的代碼評審系統。
首先當代碼提交之後並不會直接merge到中心庫裏面,它會暫時存在一個臨時庫裏面,同時生成一個代碼評審記錄,並向特定的評審人員發送請求評審的郵件。當評審者在評審代碼以後,若是經過就須要在Gerrit系統裏面對代碼進行打分,若是經過了就能夠將代碼merge到中心庫裏面去,若是沒有經過,那麼這個代碼提交就須要被返還給開發者進行修改。
與此同時它還能夠自動觸發一次包含本次代碼提交的CI構建(前提須要手工預先配置),若是CI自動構建和測試經過,也能夠自動在Gerrit系統裏面進行打分,能夠給最終進行merge的人員進行參考。示意流程見下圖。
因爲Android源代碼由上百個獨立的代碼庫組成,而且編譯一個Android系統須要大部分代碼庫裏面的代碼,因此如何管理如此多的代碼庫也是一個難題,好比如何一次性同步須要編譯一個須要支持特定設備的代碼庫組合。爲此Google基於Python語言開發一個工具叫Repo ,這個工具能夠自定義你須要的代碼庫的組合,而且一次性對這些代碼庫進行同步,好比pull和push,見下圖。
4、SVN到Git的遷移
對於想從集中式代碼管理系統遷移到分佈式代碼管理系統的團隊來說,若是團隊規模小,那麼問題通常都不大,可是對於大型分佈式團隊倒是困難重重。最主要的兩個困難:
- 代碼量太大,很難一次性將全部的代碼和日誌等在短期內遷移成功。
- 因爲下屬團隊太多,很難同一時間讓全部團隊都切換至新的代碼管理工具。
爲了解決這些難題,通常都會首先選用1個團隊來使用新的代碼版本管理工具。若是這個團隊轉換成功,再將其做爲標杆向其餘團隊推廣,從而逐步的將全部團隊切換到新的工具上去。
SVN到Git的遷移方案通常主要會使用兩種工具:
- 開源免費的git-svn;
- 商業收費的Subgit。
其中使用Subgit的遷移方案以下圖:
若是團隊組資源充足,還可使用Gerrit搭建一個獨立的Git服務器,從而以分佈式的方式進行代碼遷移,以下圖:
5、多產品線的管理
使用同一個中心代碼庫管理多產品線一直是大型項目的一個困難點,特別是使用SVN這樣的工具更是難以管理,由於SVN這種工具的Branch本質上是一個目錄拷貝,而且速度慢,並且代碼回遷也須要手動進行。可是若是使用Git的特性來管理多產品線,比起SVN是事半功倍。具體方案見下圖:
總結:
分佈式代碼版本管理系統並不必定適合全部團隊,好比中小團隊可能更關心的只是成本更低,簡單易用,那麼SVN等這類集中式版本管理工具仍是更爲適合。可是無論團隊最終選用什麼代碼版本管理工具,只要適合本身的團隊的開發流程和工做方式,而且代碼管理順暢就能夠了。
文/ThoughtWorks劉冉
原文:大型分佈式團隊的代碼版本管理 - ThoughtWorks洞見
轉自:
https://link.zhihu.com/?target=http%3A//insights.thoughtworkers.org/code-management-of-large-distributed-team/
https://www.zhihu.com/question/25491925