SVN與 CVS的比較
1.全域性的版本編號
一個新的版本,並得到一個自增量的版本號碼N+1,該版本號碼並不針對某個特定的檔案,而是全域性的、針對整個版本庫的。因此,我們可以將Subversion 的版本庫看作是一個檔案系統或檔案分類樹的數組。Subversion 的全域性版本編號為Subversion 帶來了諸多的優勢:如對目錄或檔案執行拷貝,無論涉及多少檔案,Subversion 不需要對單個檔案依次執行拷貝命令,僅僅需要建立一個指向相應的全域版本號碼的一個指標即可。
2.目錄的版本控制
CVS 只能對檔案進資料列版本設定,不能對目錄進資料列版本設定,因此CVS 沒有任何關於檔案“移動”(move) 操作的概念。當人為進行檔案移動操作時,CVS 只能注意到,一個檔案在一個位置被刪除了,而在一個新位置建立了另外一個檔案。由於它不會串連兩個操作,因此也很容易使檔案曆史軌跡丟失。設定 CVS 存放庫時,必須非常謹慎地為每個檔案選擇準確的位置,因為在設定之後,幾乎就要一直使用這個位置了。
Subversion 將目錄作為一類特殊的檔案來處理,因此,Subversion 像記錄普通檔案的修改曆史一樣記錄對目錄的修改曆史,當發生檔案/目錄的移動、重新命名或拷貝操作時,Subversion 能夠準確記錄操作前後的曆史聯絡。同樣,象對檔案的不同曆史版本進行比較一樣,Subversion支援對目錄的不同曆史版本的比較,清晰展現目錄的變化曆史。
3.原子性提交
從使用者的角度來看,CVS 和Subversion 都支援對多個檔案修改的批量提交,但二者在實現方式上存在本質的區別。
CVS 採用線性、串列的批量提交,即依次地,一個接一個地執行提交,每成功提交一個檔案,該檔案的一個新的版本即被記錄到版本庫中,提交時使用者提供的日誌資訊被重複地儲存到每一個被修改的檔案的版本曆史中。
CVS 串列批量提交模式的弊端在於 - 當任何原因造成大量操作的中斷時(典型原因包括:網路中斷、用戶端死機等),版本庫往往處於一個不一致的狀態:原本應該全部入庫的檔案只有一部分入庫,很有可能版本庫中的最新版本不能順利編譯,更為嚴重的是,隨著其他的使用者執行cvs update 操作,該不一致性將迅速在Team Dev中擴散,從而嚴重影響團隊的開發效率,並存在品質隱患。
SVN徹底消除了CVS的以上弊端。無論批量提交包含多少檔案修改,只有當全部檔案修改都成功入庫,該提交才變得有效,才對其他使用者可見;否則,無論任何原因造成中斷,SVN都會自動執行“復原”(rollback)操作。換一個說法,SVN保證所有的修改要麼全部入庫生效,要麼一個也不入庫,即對版本庫不作任何的修改。這就是SVN的原子性提交(atomic commit)。 由於SVN的原子性提交特性和全域版本編號方式,當提交成功完成時,一個唯一的、新的全域版本編號產生,而提交時使用者提供的日誌資訊與該新的版本編號關聯,只進行一次儲存(區別於CVS的按檔案重複儲存)。
4.差異化的二進位檔案處理
CVS 能夠有效處理文字檔(或ASCII檔案,原始碼檔案),可以對文字檔進行差異化的儲存、新舊版本的比較,檔案合并等;但對於二進位檔案,CVS 則明顯力不從心。
與CVS 不同,Subversion採用統一的二進位差異演算法,即對文字檔和二進位檔案採用相同的差異比較演算法,並以相同的方式在版本庫中進行儲存:每次提交後版本庫中只儲存相對於先前版本的差異,從而可以節省大量的儲存空間。
該二進位差異演算法不僅應用在版本的儲存上,更為重要的是,Subversion對二進位檔案與文字檔一視同仁,當用戶端需要擷取新的版本時(如執行svn update),在網路上只有版本的差異被傳輸,從而大大減少對網路頻寬的消耗。
5.雙向的差異化-壓縮網路傳輸
對於文字檔,CVS僅僅支援單向的差異化傳輸:從CVS伺服器到用戶端的傳輸是差異化的,即執行cvs update時,只有差異的部分從伺服器傳輸到用戶端;而當執行cvs commit時,無論代碼變化多少,CVS 都需要從用戶端向伺服器完整傳輸被修改檔案的全部內容,不能只傳輸差異。
相反,無論是文字檔還是二進位檔案,Subversion都進行雙向的差異化傳輸,並且差異化內容還要進行壓縮/解壓縮的過程。
對CVS而言,操作的成本(網路頻寬消耗是最大的操作成本)與被修改的檔案的大小成比例,而與修改本身的大小無關;對Subversion而言,操作成本只與修改本身的大小成比例,而與被修改的檔案的大小無關。因此,與CVS相比,Subversion消耗更少的網路頻寬。Subversion 更加適合基於互連網(或廣域網路)進行協作開發的地理上分布的團隊 — 版本伺服器集中、單一;用戶端廣泛分布。
6.高效、快捷建立分支和基準
CVS和Subversion都支援分支(branch)和基準(tag),CVS在建立分支的時候,需要對所有分支檔案依次進行操作,因此分支的建立成本(主要是建立分支所需的時間,或消耗的計算資源)與參與分支的檔案數量成比例,項目越大,版本庫越大,檔案越多,分支的建立成本越高;基準(tag)的建立與此類似。
Subversion的分支和基準是通過執行“拷貝”來建立的。由於Subversion的全域版本號碼特性,Subversion中分支或基準的建立過程,或Subversion中的“拷貝”過程,真正的操作是在版本庫中建立一個到某一全域版本號碼的指標,不再需要針對眾多的單個檔案依次執行操作。因此,該操作的成本為一個很小的常數,並且,分支或基準的建立不需要進行版本的冗餘儲存,建立立的分支或基準基本不佔用版本庫空間,分支的後續儲存空間的開銷也只與修改的大小有關。
7.更好的衝突標識與處理
在CVS 中,經常會出現由於使用者的疏忽(如,沒有注意到衝突,或沒有完全處理好衝突)而將仍然帶有衝突標識符號的檔案直接進行提交,從而在版本庫中產生垃圾版本。Subversion有效解決了CVS 的以上問題:Subversion記錄並保持檔案的衝突狀態,只有當使用者明確執行svn resolved命令後,該衝突狀態標識才被複位,該檔案才能被提交,從而大大減少了將仍然帶有衝突標識符號的檔案直接進行提交的可能性。
8.更多本地/離線操作
與CVS 不同的是,Subversion的.svn 目錄中還包含了工作拷貝中每一個檔案的一個“唯讀、乾淨的”副本。正是由於該副本的存在,使得Subversion 與CVS 相比,可以執行更多本地/離線操作,即某些操作不需要訪問版本程式庫伺服器,因此不需要存在從用戶端到伺服器的網路連結,當然也不消耗任何網路頻寬,這進一步增強了Subversion對廣域網路的友好支援。
9.中繼資料管理
與CVS相比,Subversion增加了中繼資料管理機制。即可以對版本庫中的檔案或目錄附加任意的“屬性”(property),並記錄屬性的變化曆史,也就是對中繼資料進行版本管理。
Subversion 中繼資料的目的是提供附件的資訊以滿足流程或過程自動化的需要,以增強Subversion 的管理能力和自動化程度。Subversion 自身就通過“屬性”來儲存一些特殊的資訊。一個使用Subversion 中繼資料的例子:可以在一些批處理的指令碼程式或Subversion的鉤子程式(hooks)中建立、訪問、修改“屬性”中繼資料來滿足流程自動化的要求。
10.整合Apache Web Server,提供更多的特性
Subversion 通過與Apache Web Server 的整合,可以提供基於http/https 協議的版本庫的訪問機制,從而支援Subversion 跨越防火牆的安全訪問。除此以外,Subversion 還可以利用更多的Apache 特性,包括但不限於:Apache 豐富的使用者認證機制(包括通過LDAP伺服器如Windows Active Directory 伺服器的使用者認證),基於目錄路徑的精細粒度的存取控制,對傳輸的網路流量進行壓縮/解壓縮,瀏覽版本庫目錄結構等等。
11.支援WebDAV
Subversion 通過與Apache Web Server 的整合,支援WebDAV協議,使得業務使用者(business users)或非技術使用者在不安裝任何版本管理用戶端的情況下輕鬆的訪問Subversion 版本庫,不改變業務使用者已有使用習慣,支援分布的業務使用者對文檔的評審、修改並實現版本控制,真正將軟體開發的生命週期從開發/技術團隊擴充到項目的全部干係人(stakeholder),避免通過電子郵件傳遞文檔的混亂與無序、通過Windows 作業系統共用造成的安全性漏洞、病毒攻擊、曆史版本被覆蓋或丟失、審計困難等諸多典型問題。
CVS與SVN比較表
比較項目 CVS SVN
許可權控制 是否依賴系統帳號 依賴 不依賴
可否對分支授權 否 是
是否支援LDAP認證 否 是
圖形化帳號管理 否 是(集中管理平台)
使用者可否擷取忘記口令,修改口令 否 是(集中管理平台)
目錄,檔案名稱變更 否 是
分支
管理 建立分支時間 耗時* 快
分支可見、查詢 難 易
二進位檔案 二進位最佳化 否 是
二進位檔案標識 手工 自動
二進位檔案(圖形檔案)被破壞 易破壞 不易破壞
事物
處理 原子提交 否 是
修改提交說明 單個檔案 是
換行
符 可否指定分行符號類型 否 是
檢查分行符號設定,避免跨平台開發帶來的混亂 否 是
功能擴充 CVSROOT hooks 指令碼
網路
頻寬 網路頻寬佔用 高 低
離線命令 否 部分