Git 、CVS、SVN比較
項目源代碼的版本管理工具中,比較常用的主要有:CVS、SVN、Git 和 Mercurial (其中,關於SVN,請參見我先前的博客:SVN常用命令 和 SVN服務器配置)
目前Google Code支持SVN、Git、Mercurial三種方式,例如:我上傳的 linux-kernel-source(Git 方式)、sdk-java(SVN方式),那么它們各有什么區別呢?
Git與CVS 的區別
-
分支更快、更容易。
-
支持離線工作;本地提交可以稍后提交到服務器上。
-
Git 提交都是原子的,且是整個項目范圍的,而不像 CVS 中一樣是對每個文件的。
-
Git 中的每個工作樹都包含一個具有完整項目歷史的倉庫。
-
沒有哪一個 Git 倉庫會天生比其他倉庫更重要。
Git與SVN 的區別
Git 不 僅僅是個版本控制系統,它也是個內容管理系統(CMS)、工作管理系統等。如果你曾是一個使用過SVN背景的人,那么你可以很容易的做一定的思想轉換,來 適應Git提供的一些概念和特征。這篇文章的主要目的就是通過介紹Git能做什么,以及它和SVN在深層次上究竟有什么不同,通過比較來幫助你更好的認識 Git
-
Git是分布式的,SVN不是
這是Git和其它非分布式的版本控制系統(SVN,CVS)最核心的區別。如果你能理解這個概念,那么你就已經上手一半了。需要做一點聲明,Git並不是目前第一個或唯一的分布式版本控制系統。還有一些系統如 Bitkeeper, Mercurial 等也是運行在分布式模式上的,但Git在這方面做的更好,而且有更多強大的功能特征。
Git 跟SVN一樣有自己的集中式版本庫或服務器。但 Git 更傾向於被使用於分布式模式,也就是每個開發人員從中心版本庫的服務器上chect out代碼后會在自己的機器上克隆一個自己的版本庫。可以這樣說,如果你被困在一個不能連接網絡的地方時,就像在飛機上,地下室,電梯里等,你仍然能夠提交文件,查看歷史版本記錄,創建項目分支等。對一些人來說,這好像沒多大用處,但當你突然遇到沒有網絡的環境時,這個將解決你的大麻煩。
同樣,這種分布式的操作模式對於開源軟件社區的開發來說也是個巨大的恩賜,你不必再像以前那樣做出補丁包,通過email方式發送出去,你只需要創建一個分支,向項目團隊發送一個推請求。這能讓你的代碼保持最新,而且不會在傳輸過程中丟失,一個這樣的優秀案例就是: GitHub.com
有些謠言傳出來說subversion將來的版本也會基於分布式模式。但至少目前還看不出來。
-
Git 把內容按元數據方式存儲,而SVN是按文件
所 有的資源控制系統都是把文件的元信息隱藏在一個類似.svn、.cvs等的文件夾里。如果你把 .git 目錄的體積大小跟.svn比較,你會發現它們差距很大。因為 .git 目錄是處於你的機器上的一個克隆版的版本庫,它擁有中心版本庫上所有的東西,例如標簽、分支、版本記錄等。
-
Git 分支和SVN的分支不同
分支在SVN中一點不特別,就是版本庫中的另外的一個目錄。如果你想知道是否合並了一個分支,你需要手工運行像這樣的命令svn propget svn:mergeinfo,來確認代碼是否被合並。所以,經常會發生有些分支被遺漏的情況。
然而,處理Git 的分支卻是相當的簡單和有趣,你可以從同一個工作目錄下快速的在幾個分支間切換。你很容易發現未被合並的分支,你能簡單而快捷的合並這些文件。
-
Git 沒有一個全局的版本號,而SVN有
目 前為止這是跟SVN相比GIT缺少的最大的一個特征。你也知道,SVN的版本號實際是任何一個相應時間的源代碼快照,它是從CVS進化到SVN的最大的一 個突破。Git 可以使用SHA-1來唯一的標識一個代碼快照,但這個並不能完全的代替SVN里容易閱讀的數字版本號。
-
Git 的內容完整性要優於SVN
Git 的內容存儲使用的是SHA-1哈希算法。這能確保代碼內容的完整性,確保在遇到磁盤故障和網絡問題時降低對版本庫的破壞。這有一個很好的關於Git 內容完整性的討論。(英文原文參考:diff)
CVS-SVN-GIT綜合比較
首先,介紹幾個版本控制軟件相互比較的重要依據:
(1)版 本庫模型(Repository model):描述了多個源碼版本庫副本間的關系,有客戶端/服務器和分布式兩種模式。在客戶端/服務器模式下,每一用戶通過客戶端訪問位於服務器的主版 本庫,每一客戶機只需保存它所關注的文件副本,對當前工作副本(working copy)的更改只有在提交到服務器之后,其它用戶才能看到對應文件的修改。而在分布式模式下,這些源碼版本庫副本間是對等的實體,用戶的機器出了保存他 們的工作副本外,還擁有本地版本庫的歷史信息。
(2)並 發模式(Concurrency model):描述了當同時對同一工作副本/文件進行更改或編輯時,如何管理這種沖突以避免產生無意義的數據,有排它鎖和合並模式。在排它鎖模式下,只有 發出請求並獲得當前文件排它鎖的用戶才能對對該文件進行更改。而在合並模式下,用戶可以隨意編輯或更改文件,但可能隨時會被通知存在沖突(兩個或多個用戶 同時編輯同一文件),於是版本控制工具或用戶需要合並更改以解決這種沖突。因此,幾乎所有的分布式版本控制軟件采用合並方式解決並發沖突。
(3)歷史模式(History model):描述了如何在版本庫中存貯文件的更改信息,有快照和改變集兩種模式。在快照模式下,版本庫會分別存儲更改發生前后的工作副本;而在改變集模式下,版本庫除了保存更改發生前的工作副本外,只保存更改發生后的改變信息。
(4)變更范圍(Scope of change):描述了版本編號是針對單個文件還是整個目錄樹。
(5)網絡協議(Network protocols):描述了多個版本庫間進行同步時采用的網絡協議。
(6)原子提交性(Atomic commit):描述了在提交更改時,能否保證所有更改要么全部提交或合並,要么不會發生任何改變。
(7)部分克隆(Partial checkout/clone):是否支持只拷貝版本庫中特定的子目錄。
名稱 |
版本庫模型 |
並發模式 |
歷史模式 |
變更范圍 |
網絡協議 |
原子提交性 |
部分克隆 |
CVS |
Client-server |
Merge |
Changeset |
File |
Pserver,ssh |
No |
Yes |
SVN |
Client-server |
3-way merge, recursive merge, octopus merge |
Changeset and Snapshot |
Tree |
custom (svn), custom (svn) over ssh, HTTP and SSL (usingWebDAV) |
Yes |
Yes |
Git |
Distributed |
Merge or lock |
Snapshot |
Tree |
custom, custom over ssh, rsync, HTTP/HTTPS, email, bundles |
Yes |
No |
Trunk、Branches、Tags 區別:
Trunk:軟件開發過程中的主線,開發時版本存放的目錄,即在開發階段的代碼都提交到該目錄上,保存了從版本庫建立到當前的信息。
Branches:軟件開發過程中的分支,發布版本存放的目錄,即項目上線時發布的穩定版本存放在該目錄中,保存了從版本庫的某一特定點(不一定是版本庫建立時)到當前的信息。
tags:表示標簽存放的目錄,tags只可讀,不可寫
分支主要用於在不影響Trunk其它用戶情況下進行一些關於新功能的探索性或實驗性的開發,待新功能完善后它也可以合並到Trunk中。
(原文,請參考我在百度空間的博客:Git 命令參數及用法詳解)