代碼版本控制用SVN還是Git好?

SVN和Git都有分支,現在需要對代碼進行版本控制,都各有什麼優缺點?兩者都有用過,但是僅限於會使用,更多的利弊還是不太了解。公司對目錄許可權訪問控制要求嚴格,員工之前一直用的SVN。現在是打算都用


代碼版本管理系統的歷史

代碼版本管理系統大致可以分為三個時代:

第一代:本地式

這代主要的特點提供本地代碼版本控制,比如SCCS(1972)、 PVCS(1985)等。

這代主要實現了基本的代碼版本管理,但缺點是無法讓多人同時對一個版本庫進行修改。這個也和當時軟體規模不夠大有關,也沒有這樣的需求。

第二代:客戶端-伺服器式

這代主要的特點是提供集中式伺服器端代碼版本控制,比如 CVS(1986), ClearCase(1992), Visual SourceSafe(1994), Perforce(1995), Subversion(2000) 等。

這代主要是實現了中心伺服器端的代碼版本管理,特點是可以讓多人同時對一個代碼版本庫進行同步和修改,但缺點也相當明顯:

  1. 在無法連接伺服器的情況下,無法查看日誌以及提交和比較代碼版本(慢速網路和遠程異地工作的程序員的痛),以及當服務或者網路出現問題的時候很多人員就會無法工作。
  2. 不支持local branch,導致branch創建管理複雜,並且一旦創建就很難修改(快速迭代開發中的程序員的痛)
  3. 由於只有一個中心端伺服器,一旦發生災難性問題,那麼所有日誌都會丟失,所以需要經常做備份(備份需要不小的成本)
  4. 如果軟體代碼量過於龐大,一般會出現速度緩慢的情況,因為每次的日誌查詢、不同版本之間的代碼比較和代碼提交等操作都需要和伺服器通信,造成伺服器端的負載過大。

第三代:分散式

這代主要的特點是提供分散式代碼版本控制,比如Git(2005), Mercurial(2005)等。

這代結合了第一代和第二代的優點並實現了分散式的代碼版本管理。

這代的優點:分散式管理,在沒有和伺服器有連接的情況下仍然可以查看日誌,提交代碼,創建分支;支持local branch,可以快速方便的實現各種分支管理;支持分散式,從而可以實現分塊管理,以及負載分流管理。

缺點是有一定的學習曲線,比如分布方式下的代碼同步,local branch的理解與運用,分散式代碼管理的理解與運用等。詳細的比較可以參考:這裡。

二、大型分散式團隊

曾經有這樣一個分散式團隊,他們在多個城市都有小分隊,並且正在開發一個大型項目,見下圖

他們使用的代碼版本管理工具是第二代代碼管理工具SVN,管理方案如下:

但是他們在使用的過程中卻遇到了下面這些問題與痛點。

由於是分散式團隊,所以:

  • 基於團隊的代碼模塊分離困難

當伺服器不可用時:

  • 不能查看提交記錄
  • 不能比較文件
  • 不能提交代碼

創建代碼分支時:

  • 分支創建速度慢
  • 多分支管理困難

在提交代碼時:

  • 希望有Code Review
  • 希望有CI Review

因為代碼龐大:

  • 查看日誌慢

備份代碼庫的時候:

  • 需要停機備份
  • 備份成本高

針對以上問題,可以使用新一代的分散式的代碼版本管理系統來解決,見下圖:

其中每一個團隊都有自己獨立的代碼庫,有一個中心庫用於同步這些獨立的代碼庫,並且每個庫都由團隊自己管理和維護。而且代碼版本管理系統需要支持輕量分支,代碼評審,離線提交,離線查看日誌等功能。

但是由於當前沒有一個單一的代碼版本管理工具能同時滿足以上所有需求,所以很多公司都基於它們開發集成管理系統,比如Gerrit,GitLab,GitHub,BitBucket等。其中的Gerrit由於其開源,免費,以及由Google開發和維護,並管理著Android,OpenStack等大型項目源代碼的特點,成為了大型分散式團隊優先選擇的系統。

三、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,見下圖。

四、SVN到Git的遷移

對於想從集中式代碼管理系統遷移到分散式代碼管理系統的團隊來講,如果團隊規模小,那麼問題一般都不大,但是對於大型分散式團隊卻是困難重重。最主要的兩個困難:

  1. 代碼量太大,很難一次性將所有的代碼和日誌等在短時間內遷移成功。
  2. 由於下屬團隊太多,很難同一時間讓所有團隊都切換至新的代碼管理工具。

為了解決這些難題,一般都會首先選用1個團隊來使用新的代碼版本管理工具。如果這個團隊轉換成功,再將其作為標杆向其他團隊推廣,從而逐步的將所有團隊切換到新的工具上去。

SVN到Git的遷移方案一般主要會使用兩種工具:

  1. 開源免費的git-svn;
  2. 商業收費的Subgit。

其中使用Subgit的遷移方案如下圖:

如果團隊組資源充足,還可以使用Gerrit搭建一個獨立的Git伺服器,從而以分散式的方式進行代碼遷移,如下圖:

五、多產品線的管理

使用同一個中心代碼庫管理多產品線一直是大型項目的一個困難點,特別是使用SVN這樣的工具更是難以管理,因為SVN這種工具的Branch本質上是一個目錄拷貝,並且速度慢,而且代碼回遷也需要手動進行。但是如果使用Git的特性來管理多產品線,比起SVN是事半功倍。具體方案見下圖:

總結:

分散式代碼版本管理系統並不一定適合所有團隊,比如中小團隊可能更關心的只是成本更低,簡單易用,那麼SVN等這類集中式版本管理工具還是更為適合。但是不管團隊最終選用什麼代碼版本管理工具,只要適合自己的團隊的開發流程和工作方式,並且代碼管理順暢就可以了。

文/ThoughtWorks劉冉 原文:大型分散式團隊的代碼版本管理 - ThoughtWorks洞見


不評價那個好,兩個是不同的東西。

但是,上面那些黑 SVN 的兄弟們,你們真的懂 SVN 嗎?

SVN屬於被淘汰的上一代版本管理工具。用SVN,你就屬於被淘汰的一類。

此句無力吐槽……

比如說隊里的熊孩子搞砸了,一連幾個commit都不能編譯。太簡單了:用git rebase -i可以把一條branch上的壞commit一個一個剔掉。換了SVN,提交了壞代碼的話,天皇老子都沒法改。

revert change 很easy 的丫親!

不會 github 的程序員我不會發 offer。

老大,別這麼絕對好嗎?沒入黨也可以當選村官啊!!

svn的缺點主要是不能離線提交

不能夠離線提交不是缺點,是 feature!是 feature!是 feature!你確定你的 Build machine 需要「離線提交」嗎?你確定你的兄弟「離線提交」了一個fix,產品上的 bug 就真的 fix 了嗎???

"另外,SVN 還有一大弊端,當團隊合併文件時,如果有兩人上傳發生衝突則需管理員協調完成後其他成員才可繼續上傳"。

衝突是在本地的,在本地解決衝突的時候,根本不會影響到其它人上傳好嗎?

還有說 SVN 不能夠做分支的,我就不再說什麼了。。

利益相關:

在世界500強公司的 Build Release team 工作,專業做持續集成(Continuous Integration)。

目前用「上一代」版本管理工具 SVN,外加 Jenkins、JIRA、MSBuild、PowerShell 等工具來服務分布在美國、紐西蘭、澳大利亞、英國、印度、上海、貝爾格萊德、倫敦等世界各地的研發 team 的代碼構建和產品發布。

公司有 55000 個人,寫代碼的研發團隊不知道一共多少人。但我這裡看得見的有在用 SVN 的至少有 1000 人。

基於這些工具,去年我們的軟體在5個活躍分支上一共交付了 62 個 release…客戶們都點贊…

當然,也用過 Git。Git 很棒!基於 Github 社區的支持,它可以說是分散式源碼管理工具里最流行的。


svn 好學不好用

git 好用不好學

hg (學名叫 mercurial) 其實更好。有 svn 的好學也有 git 的好用。

有關這個問題我講個故事:

在我們決定由 svn 切換到分散式版本管理時。

我們曾經爆發過一起關於使用 hg 還是 git 的爭論。

因為有個支持 git 的大牛存在,所以 git 派佔了上風。於是一部分項目用上了 git 。

結果就是每當遇到 git 的問題時都得去找他。他總得不斷的幫人解決 git 問題。

再後來,那個大牛走了。然後就再也沒有人會搗鼓 git。

然後大家都乖乖的用上 hg 了,從此再也不需要求助任何大牛。

好吧,你可以認為我是來宣傳 hg 的,但是想起輪子哥的這個帖子:為什麼有人熱衷於吵哪個計算機語言好?

我突然意識到,如果不站出來宣傳讓更多的人用更好用的 hg 替代反人類的 git ,也許後果會跟那個帖子中說的那樣。

當然,補充一下,如果你的企業需要實施精確到目錄級別的許可權控制,那麼 svn 還是有不可替代的優勢。


毫無疑問是 git 。因為有 github 。

共享的利好遠遠大於技術上的優勢或者學習曲線的陡峭。不會 github 的程序員我不會發 offer 。


好怎麼定義?

如果是說適合與否的話,視團隊而定吧。就算是同樣用 SVN 或者 Git,我在不同公司看到過的用法也不盡相同。

吐槽一下:很多人說 Git 毋庸置疑比 SVN 和 CVS 好,我就不知道如果他媽的只有 3 個人的團隊,10 個頁面,Git 可以好用在哪裡……


知乎首答,最近被這個爭論已經弄得想死了,實在忍不住了。以下所有觀點針對以商業軟體盈利的公司管理模式,freelancer和喜歡做project當做reference的可以跳過

首先,我不認同這兩個完全不同模式的版本管理工具有好壞之分。一個集中式,一個分散式,我認為這是沒有什麼爭論點的。

第二,對於一個發布商業軟體的公司,真的需要分散式管理嗎,難道員工無法保證大部分時間在同一地點上班?難道一個商業公司的商業軟體需要fork很多版本發布?難道對於一個商業公司的商業軟體,集中式管理和集中式發布不是最重要的嗎

第三,離線的特性真的爽?真的需要?自己和自己玩很有趣?又有多少時間是飛機上coding?無人島coding?

第四,ok,離線很酷,那無法設置分層式的許可權,ok,git腦殘粉可以說我們可以建很多branch

第五,我一直覺得svn的revert功能比git不知道好用到哪裡去了,移除bad code天皇老子都沒法改。。。太酷了,就算SVN是所謂的落後,但是對於一個使用了這麼多年的成熟產品,核心功能有缺陷,居然今天git出來了才被發現?無法移除bad code。。。那要version control幹什麼...

第六,我一直覺得2,3個人的特別是創業公司搞個git,pull來push去,每天幾十個branch的,也是醉了,然後動不動簡歷上放十多個git的project,那是多麼的酷炫~已經完全偏離了git對於分散式開發和開源項目貢獻的初衷了

其他,學習成本的對比已經成本和產出的性價比,那就是自行比較了

不會 github 的程序員我不會發 offer。

ps:千萬不要亂髮offer,深坑滲入。事物都有兩面性,用的爽的才是最好的,如此絕對和不理性的創業者,再特性都沒了解清楚的情況下馬上可以變身FQ的CTO..

呵呵


git比較適合社交吧。


當一個團隊中不受控因素偏多,尤其是有不怎麼懂技術的配置MM參與時,SVN幾乎是唯一選擇。Git對人要求高,學習成本和部署成本卡死一堆人。另外還有繞不過去的許可權問題。


等你常用分支的時候,你會知道Git比Svn要好用不止一個數量級!


如果你只能在SVN和git中間選的話那隻能是Git了,不過如果不想因為不熟悉git就天天出翔的話,你可以嘗試一下TFS或者Hg,對初學者和團隊合作都十分友好。


開源鬆散的團隊就用 Git,統一、分工嚴明的團隊就用 SVN。自己做的話選你喜歡的。


SVN屬於被淘汰的上一代版本管理工具。用SVN,你就屬於被淘汰的一類。

GIT牛掰不僅僅是牛掰在離線提交這個方面。事實上本座的團隊使用GIT根本沒有考慮是否能離線提交,每個開發人員基本上走到哪裡都可以有網,離不離線不是關鍵問題。

GIT牛掰的地方在於對分支管理,子項目依賴,代碼衝突管理上比SVN高出不止一個數量級。

舉個例子:用一個開源的庫,我們需要對開源的庫某些部分進行修改,但是又想保證該庫緊跟官方發布不過時。用SVN的話,要不一切手動,要不你就把你的修改提交到官方源去(基本上是不可能的)。用GIT,我可以克隆一個repository,新建一條branch保持私有修改,官方庫有更新隨時pull --rebase。

GIT的commit還可以亂序修改。比如說隊里的熊孩子搞砸了,一連幾個commit都不能編譯。太簡單了:用git rebase -i可以把一條branch上的壞commit一個一個剔掉。換了SVN,提交了壞代碼的話,天皇老子都沒法改。

GIT的高級玩法多了去了。學習曲線比SVN要陡,但是培訓下團隊完全是值得的。現在業界主流都用GIT,數不清的各種工具和雲服務都基於GIT。上Github下個代碼,人家很瀟洒地一站式git clone,你下個zip再解包不寒磣?

就算你是單幹,GIT也比SVN好用的多。用SVN如果不用雲服務的話你還得自己架一個SVN伺服器,GIT的話直接本地repository。


How an svn user sees git workflow

不解釋


反正裝了Tortoise Git Hg SVN之後都差不多

你做小項目就用用git好了


沒有 GitHub 的話,肯定是 hg,因為有了 GitHub 妥妥 git ,至於 svn,大部分團隊都不合適吧


1 幾乎所有程序員,不管有沒有「假裝big」,都會推崇git的~~這大方向沒什麼錯~

2 如果是不到十人的小團隊小項目這種特例,還是svn好點(個人意見)。畢竟學習等其他各種成本是個很現實的問題。


伺服器用svn,本地用git-svn也不錯,既有svn的子目錄許可權控制功能又有git的離線提交功能。


SVN適合使用人數相對較少的項目


當管理很多小項目時,還是svn方便,可以建一個repository, 把項目都放在裡面。可以checkout 某個項目,修改,提交。

Git需要checkout 整個repository.


Mercurial也還不錯。


推薦閱讀:

Git算不算程序員的必備技能?
代碼寫得好,但是不會(不願)使用 Git 之類的代碼管理工具能稱得上是優秀程序員嗎?
Github上都有哪些有用但不為大家熟知的小功能?
git clone一個github上的倉庫,太慢,經常連接失敗,但是github官網流暢訪問,為什麼?
一個人寫程序,版本控制用svn還是git?

TAG:版本控制系統 | Git | SVNSubversion |