02 SVN 與 Git 的優缺點

上一篇部落格大致聊了聊關於版本控制系統的周邊,這一篇我們就來繼續嘮嘮作為近年來最受歡迎的兩個版本控制系統的優缺點吧。

聊優缺點之前,先簡單了解一下這兩個這兩個版本控制系統好了:

關於 SVN

SVN 概述

SVN 毫無疑問是一個縮寫,它的全稱是:Subversion,名字源於創作者之一的 Ben Collins-Sussman ,中文釋義:「顛覆」,意為顛覆 CVS 的版本。

SVN 是 CollabNet 於 2000 年創建的開源項目,創作初衷是為了對當時最受歡迎的版本控制系統 CVS 進行修正和補充。

在2000年2月項目創建之初他們就愉快地聯繫上了 CVS 的「親媽」——Open Source Development with CVS(Coriolis, 1999)的作者 Karl Fogel,邀請他一同為這個新項目工作,而 Karl 本人也因在使用 CVS 時受到束縛而在考慮如何改進創新,故此一拍即合,欣然拉著和他有相同想法的朋友—— Ben Collins-Sussman ,一起參與了 SVN 的開發工作。

由於初衷是對 CVS 的修復與補充,故此 SVN 保留著與 CVS 相同的開發模型,使得 CVS 的用戶可以不費什麼力氣地從 CVS 轉換至 SVN 。

SVN 的工作流程

和 CVS 一樣 SVN 是集中式版本控制系統,其核心在於版本庫只在中央伺服器上,所有想要獲取、想要更改其內容的人都必須通過互聯網的途徑連接中央倉庫。

言語太過蒼白,直接上圖吧:

SVN流程圖.png (693×235) (gitee.com)

由上圖可以清晰地感受到,實際上中央版本庫就是一個大型的「資源共享場地」或者說是一個「情報局」——如果把提交上去的項目看作情報或者資源的話。

舉個栗子:

如果把一個放進 SVN 的公司項目比作一個”情報局”,那麼每一個參與這個項目的人都是可以從這個「情報局」獲取情報的成員,

每一個成員獲取或是更改「情報」都必須在「情報局」全方位觀測的情況下——獲取或更改等操作必須全程聯網。

不同的成員能獲取到的「情報內容」有所不同——因為 SVN 有許可權管理,但只能根據「情報類型」——只能設置目錄的訪問許可權,不能設置單個文件的訪問許可權。

如果多個成員都在更改同一則「情報」,大多數情況下都需要拼手速,要是有人先一步將自己更改過的「情報」上交,那後面的人就只會被無情地阻擋。若想繼續將自己更改內容提交,只能先獲取已被更改過的「情報」,再更改自己想更改的內容,進一步提交。要是此時又有人捷足先登,那隻能苦逼地繼續先獲取再更改了。

「情報局」也為提供「情報」的成員設立單人間,成員可以將自己要更改的「情報」帶進單人間進行操作,更改之後再將「情報」帶出來上交,完美地解決了拼手速的問題——文件鎖。

事實上,光是有「單間」是遠遠不夠的。文件鎖同樣存在著很大一部分問題:比如加鎖的人改完文件忘解鎖了;比如雖然想改的是同一個文件,但相互之間互不干擾,本可以並行的,加了鎖無法並行,降低了效率;比如因為文件鎖的存在給人一種安全的錯覺,所以更改的時候並沒有事先商量,結果雖然改的是不同的文件,但文件間相互關聯,修改的內容在語義上並不兼容,再提交……哦,那畫面太美我不敢想。

所以 SVN 又提出了另一解決方案——「複製-修改-合併方案」——每一個用戶的客戶端都與倉庫通訊,在本地創建一份私有的工作副本,然後用戶可以同時地互不干擾地修改自己的私有副本,最後將私有副本合併為一個新的最終版本,當然, SVN 會提供合併操作,但歸根結底,必須由用戶自己來確保合併的結果是正確的。

沿用上面那個例子就是:如果有多個成員對同一份「情報」有異議想更改,那麼「情報局」就會讓你們各自將「情報」複製一份,自己拿去修改,修改完上交「情報局」,「情報局」也會幫忙把這幾份修改過的「情報」統籌之後收錄為新版本,但「情報局」並不能保證它統籌過後的「情報」是否準確,需要成員們自行去確認或修正「情報」的準確性。

這個「複製-修改-合併方案」是不是很耳熟?ε=(´ο`*)))唉,人類的發展就是一個相互借鑒、相互成長的過程吶。

SVN的特點:

  1. 擁有統一的版本號。和 CVS 對每一個文件按順序編排版本號不同,SVN 任何一次提交都會將所有文件增加到同一個新版本號,即使是該次提交不涉及到的文件,這樣就使得擁有同一版本號的所有文件集體構成軟體的一個版本。
  2. 原子提交。每次提交不管是單個或是多個文件,都是以文件作為一個整體提交的,如果傳輸過程被中斷之類的,也不會引起資料庫的不完整和數據損壞。
  3. 對於重命名、複製、刪除文件等這些操作都會保存在版本歷史記錄中。
  4. 原理上只關心文件內容的具體差異。每次記錄有哪些文件作了更新,以及都更新了哪些行的什麼內容。只保存與上一版不同之處,極大地節約了空間。
  5. 目錄也有版本歷史。整個目錄樹可以被移動或者複製,操作很簡單,而且能夠保留全部版本記錄。
  6. 分支的開銷非常小。
  7. 優化過的資料庫訪問,使得一些操作不必訪問資料庫就可以做到。這樣減少了很多不必要的和資料庫主機之間的網路流量。
  8. 支援元數據(Metadata)管理。每個目錄或文件都可以定義屬性(Property),它是一些隱藏的鍵值對,用戶可以自定義屬性內容,而且屬性和文件內容一樣在版本控制範圍內。
  9. 文件鎖。支援文件鎖定。如果一個人想更改文件,那他可以在修改之前對文件進行「加鎖」,如果他已經鎖住了文件,別人就不能再對同一文件進行加鎖,也不能修改文件,只能等他完成修改然後釋放鎖,等他解鎖之後,其他人才能對該文件新版本進行上鎖編輯。
  10. 支援 FSFS 和Berkeley DB兩種資料庫格式
  11. 集中式版本控制,方便管理文檔。

關於Git

Git概述

創建 Git 的大神曾自嘲自己編輯的這個版本控制系統為」愚蠢的內容跟蹤器「。

與 SVN 不同 Git 最初的開發動力來自於 BitKeeperMonotone ,起因是 Linux 之父 Linus Torvalds 在 2002年決定啟用 BitKeeper 來作為 Linux 內核的版本控制系統。雖然 BitKeeper 不是開源項目引起了社區內一些人的不滿,但人家願意為 Linux 提供免費的服務(免費的多香啊),所以還是有驚無險地度過了兩三年時光;直到 Linux 社區中有人試圖用自己的程式碼自行連接 BitKeeper 的存儲庫,還被發現了……

道歉是不可能道歉的,所以 BitMover 關停了 BitKeeper 對 Linux 的免費支援,所以本來也有此意向的 Linux 之父用 C 語言開啟了他為期十天的 Git 創作,然後 Git 誕生了。

Git 最初版本發佈於2005年7月11號,作為 Linux 內核主要的版本控制系統,它也是一個開源項目。與 CVS 和 SVN 這類集中式版本控制系統不同,它採用分散式版本庫的方法,使源程式碼的發布和交流及其方便。

同時,Git 本著開源自由的主義精神,並沒有對版本庫的瀏覽和修改做任何的許可權限制,通過其他工具也能夠達到有限的許可權控制。得益於此,Git 不再局限於原來的活動範圍—— Linux 和 Unix,為廣大Windows用戶帶來了福音。

Git工作流程

git 是分散式的版本控制系統,它由公共版本庫和本地版本庫組成,將項目主題存放在公共版本庫中,每個開發者都可以通過克隆,在本地機器上拷貝出一個完整的Git倉庫。

Git流程圖.png (720×368) (gitee.com)

沒找著可以用的圖,手殘換了一張,將就看吧,大概就這個意思

公共版本庫可以放在伺服器上、放在網站上、放在任一本地機器上都可以。需要進行操作時,先從公共版本庫中拉取最新版本到本地,然後再進行修改,如果沒有網的情況下也可以先進行修改,提交到本地倉庫,等有網的時候再進行拉取,推送等操作。

因為每一個本地庫都有完整的git倉庫,且編輯的時候都在本地進行的,所以也就不會存在需要拼手速搶著提交的問題。但是,每一推送前最好都拉取一遍,防止你在編輯的過程中有人向公共版本庫推送了他自己的修改,如果對方修改的內容與你修改的內容不衝突,那麼直接推送是沒有問題的, Git 有相應的合併操作;要是對方修改的內容與你改的內容有衝突, Git 也提供了相應的工具(resolve)去供開發者們手動調解衝突。衝突調解完成後,就可以繼續推送了。

這一步操作是不是很眼熟?是的,這就是前面借鑒的對象。

Git的特點:

  1. 得益於它分散式的特點,很多操作都可以在本地進行,致使幾乎除了克隆以外的其他操作都十分地快速。
  2. 遠端與本地都保存著完整的git倉庫(包括程式碼與版本資訊等),編輯過程中不需要聯網,可以等有網的時候在進行推送;且每個用戶基本上都有完整備份。如果發生崩潰或損壞,可以向上推每個副本以替換。
  3. 不需要伺服器端軟體,可以運作版本控制。使得源程式碼的發布和交流及其方便。
  4. 只關心文件數據的整體是否發生變化。不保存文件內容前後變化的差異數據。更像是把變化的文件作快照後,記錄在一個微型的文件系統中。每次提交更新時,縱覽一遍所有文件的指紋資訊並對文件作一快照,然後保存一個指向這次快照的索引。為提高性能,若文件沒有變化,不會再次保存,而只對上次保存的快照作一連接。
  5. 分支的本質是一個指向提交快照的指針,速度快,靈活,分支之間可以任意切換。
  6. 可以同時擁有多個完全獨立的本地分支,這些分支的創建、合併和刪除操作只需要幾秒,分支之間的切換更是絲般順滑,且在推送遠端的時候可以選擇性推送共享分支,而不是將所有的分支都推送上去。
  7. 它使用的數據模型可確保項目每個部分的加密完整性。所有的數據在存儲前都計算校驗和,然後以校驗和來引用。 這意味著不可能在它不知情時更改任何文件內容或目錄內容

SVN 與 Git 各自的優劣

前面描述他們的時候,也大致聊了聊我所了解到的他們各自的特點,這裡也聊聊他們各自的優勢、劣勢吧。

SVN 的優勢:

  1. 用法簡單,易上手,沒有 Git 那麼多的命令,對新手比較友好。
  2. 易於管理,對許可權的管理相當嚴格,可以按組、個人針對某個子目錄的許可權控制。
  3. 文檔鎖一定意義上真的非常有用,尤其是分工明確,且不願意讓別人碰自己程式碼的時候。
  4. 本地設備上的文件更小,更省記憶體,尤其是做大項目的時候,對電腦記憶體比較友好。
  5. 可以單獨檢出某個有許可權的目錄。
  6. 有全局版本號——不需要手動編號。

SVN 的劣勢:

  1. 項目放在中央伺服器中,一旦伺服器出現什麼意外,就會損失慘重。
  2. 斷網意味著不能工作,比較扎心。聯內網還好,聯外網能卡得你懷疑人生。
  3. 人一多伺服器就有點遭不住,尤其是那種大型開源項目。
  4. 分支管理不靈活,svn分支是一個完整的目錄,且這個目錄擁有完整的實際文件,這些操作都是在服務端進行同步的,不是本地化操作,如果要刪除分支,也是需要將遠程的分支進行刪除,這會導致大家都得同步。

Git的優勢:

  1. 速度快,靈活。
  2. 離線工作。
  3. 十分詳細且忠實地反映版本間的變化,能夠及時且方便地解決衝突。
  4. 擁有多個完整獨立的分支,且可以只選擇推送共享分支。
  5. 本地擁有完整的 git 版本庫,無論損壞了那一邊,都能夠通過克隆的方式恢復。

Git的劣勢:

  1. 許可權管理形同虛設,幾乎所有人都能獲取更改全部文件,難保會不會有傻缺更改注釋不全的程式碼,導致報錯……而且也很容易被人扒源碼掛網上。
  2. 模式上比 SVN 複雜,相對的學習周期更長。

大致就這些吧,可能還不是很詳細,原本也沒想到會整理那麼久,頭都要大了。要是還有不全的,就交給未來的自己補充吧,下面是我在整理學習的時候參看的內容。大佬們寫的也都很詳細,很不錯,要是看完上面還不懂的話,不要猶豫,順著網線通過鏈接去膜拜大佬吧。

麻煩轉載引用的一定要標註來源呀。

參考資料(排名不分先後)

Subversion – 維基百科,自由的百科全書 (wikipedia.org)

git – 維基百科,自由的百科全書 (wikipedia.org)

林納斯·托瓦茲 – 維基百科,自由的百科全書 (wikipedia.org)

subversion_百度百科 (baidu.com)

Subversion 版本控制-中文幫助文檔[加鎖-修改-解鎖 解決方案] (red-bean.com)

關於 – git (git-scm.com)

GIT(分散式版本控制系統)_百度百科 (baidu.com)

Svn和Git的一次詳細對比 – ic翼 (bingyishow.top)

Git和SVN的區別 – 慕塵 – 部落格園 (cnblogs.com)

對比 Git 與 SVN,這篇講的很易懂 – SegmentFault 思否

SVN與Git比較的優缺點差異 – Tse先生 – 部落格園 (cnblogs.com)

版本控制工具 – git和svn(優缺點對比) – 程式設計師大本營 (pianshen.com)