CVS SVN VSS 使用對比

版本控制系統裏團隊開發不免要用上CVS SVN VSS ClearCase等工具。至於選擇上,則是根據開發團隊搭建的平臺,使用的編程語言相關聯。

 

如果用.net平臺開發,VSS無疑首選,儘管它曾經有不經時事的詬病,現在發展的功能也蠻強的。如果有服務器linux系統,則CVS,SVN都可以選擇。現在SVN大有取代CVS之勢。然而很多古老的程序員還是對CVS情有獨鍾。

 

如下節選一些網上的對比說明,我作以綜述。當然,真正要弄懂這些版本控制系統,還是要花費巨大工夫學習研究,不可能在baidu或者google幾下就能完成的。

 

一、Subversion包含絕大部分CVS功能

 

Subversion 作爲CVS 的重寫版和改進版,其目標就是作爲一個更好的版本控制軟件,取代目前流行的CVS。Subversion 的主要開發人員都是業界知名的CVS 專家。Subversion支持絕大部分的CVS 功能/命令;Subversion 的命令風格和界面也與CVS 非常接近。當然,不同的地方正是對CVS 的改進。

 

二、全局性的版本編號

 

一個新的版本,並得到一個自增量的版本號N+1,該版本號並不針對某個特定的文件,而是全局性的、針對整個版本庫的。因此,我們可以將Subversion 的版本庫看作是一個文件系統或文件目錄樹的數組。

 

從技術的角度來說,在Subversion 中,"文件foo.c 的第5 版本"這個說法是錯誤的;正確的說法應該是:"文件foo.c 在版本庫被修改了5 次,即執行5 次commit 後是什麼樣子?"。顯然,在Subversion 中,版本庫被修改5 次後foo.c 的內容,和被修改了6 次後foo.c 的內容很可能完全一樣,因爲版本庫的第6 次修改很可能只修改了版本庫的其他部分,而並沒有對foo.c 的進行修改。相反,在CVS 中,文件foo.c 的第1.1 版本和第1.2 版本總是不同的。

 

Subversion 的全局性版本編號爲Subversion 帶來了諸多的優勢:如對目錄或文件執行拷貝,無論涉及多少文件,Subversion 不需要對單個文件依次執行拷貝命令,僅僅需要建立一個指向相應的全局版本號的一個指針即可。

 

三、目錄的版本控制

 

CVS 只能對文件進行版本控制,不能對目錄進行版本控制,因此CVS 沒有任何關於文件"移動"(move)操作的概念。當人爲進行文件移動操作時,CVS 只能注意到,一個文件在一個位置被刪除了,而在一個新位置創建了另外一個文件。由於它不會連接兩個操作,因此也很容易使文件歷史軌跡丟失。設置 CVS 存儲庫時,必須非常謹慎地爲每個文件選擇準確的位置,因爲在設置之後,幾乎就要一直使用這個位置了。

 

同樣由於CVS 不記錄目錄的版本歷史,CVS 不支持對文件的"重命名"(rename),人爲的對文件進行重命名會使得命名前後的文件失去歷史聯繫,而記錄歷史本來是版本管理的主要目的。

 

還有,CVS 不支持對文件的"拷貝"(copy),人爲的拷貝對CVS 而言,只能看到新的文件的增加,而不能記錄拷貝源文件和目標文件之間的聯繫。

 

綜上所述,缺乏對文件"移動"、"重命名"、"拷貝"的支持的根源在於CVS 不能記錄目錄的版本歷史,而這些操作在當前的軟件開發過程中經常發生,這正是Subversion被開發並取代CVS 的主要原因之一。

 

Subversion 將目錄作爲一類特殊的文件來處理(事實上,從文件系統的角度來看,目錄確實是一類特殊的文件,當目錄中的子目錄/文件被刪除、重命名、或新的子目錄/文件被創建時,目錄的內容將發生改變)。因此,Subversion 象記錄普通文件的修改歷史一樣記錄對目錄的修改歷史,當發生文件/目錄的移動、重命名或拷貝操作時,Subversion 能夠準確記錄操作前後的歷史聯繫。同樣,象對文件的不同歷史版本進行比較一樣,Subversion支持對目錄的不同歷史版本的比較,清晰展現目錄的變化歷史。

 

四、原子性提交

 

從使用者的角度來看,CVS 和Subversion 都支持對多個文件修改的批量提交,但二者在實現方式上存在本質的區別。

 

CVS 採用線性、串行的批量提交,即依次地,一個接一個地執行提交,每成功提交一個文件,該文件的一個新的版本即被記錄到版本庫中,提交時用戶提供的日誌信息被重複地存儲到每一個被修改的文件的版本歷史中。

 

CVS 串行批量提交模式的弊端在於 -當任何原因造成批量操作的中斷時(典型原因包括:網絡中斷、客戶端死機等),版本庫往往處於一個不一致的狀態:原本應該全部入庫的文件只有一部分入庫,很有可能版本庫中的最新版本不能順利編譯,更爲嚴重的是,隨着其他的用戶執行cvs update 操作,該不一致性將迅速在開發團隊中擴散,從而嚴重影響團隊的開發效率,並存在質量隱患。另外,假如該批量提交的中斷沒有被及時發現,開發團隊往往要花更多的時間進行軟件調試和排錯。

 

CVS 即使在批量提交不發生中斷時也會造成不一致:假設用戶A 啓動一個需要較長時間才能完成的批量提交;與此同時,用戶B 執行cvs update 操作。此時,用戶B 很有可能得到一個不一致的更新,即用戶B 通過"更新"操作,得到用戶A 的部分修改文件。

 

Subversion 徹底消除了CVS 的以上弊端。無論批量提交包含多少文件修改,只有當全部文件修改都成功入庫,該提交才變得有效,纔對其他用戶可見;否則,無論任何原因造成中斷,Subversion 都會自動執行"回滾"(rollback)操作。換一個說法,Subversion 保證所有的修改要麼全部入庫生效,要麼一個也不入庫,即對版本庫不作任何的修改。這就是Subversion 的原子性提交(atomic commit)。

 

由於Subversion 的原子性提交特性和全局版本編號方式,當提交成功完成時,一個唯一的、新的全局版本編號產生,而提交時用戶提供的日誌信息與該新的版本編號關聯,只進行一次存儲(區別於CVS 的按文件重複存儲)。

 

五、支持變更集概念

 

由於Subversion 的所有提交是原子性的,每次成功提交形成的唯一的全局版本號對應此次批量提交的所有文件修改,也就是說,一個Subversion 版本號其實對應了一個邏輯上的變更集(change set),該變更集可能對應於對一個BUG 的修復,或者對應於對一個已有功能的改進,或者對應於一個新功能的實現。可以說,變更集是一個軟件開發活動的邏輯結果,該變更集可以通過其對應的版本號在軟件開發的其他過程中(如軟件合併/集成過程,軟件發佈管理,變更管理系統,缺陷追蹤系統)被引用。因此,Subversion 將版本管理從單純的、單個的文件修改的層次通過邏輯上的抽象,上升到更便於理解和交流的開發活動的層次。

 

六、差異化的二進制文件處理

 

由於歷史原因,CVS 主要是爲早期的程序員設計的,CVS 能夠有效處理文本文件(或ASCII文件,源代碼文件),可以對文本文件進行差異化的存儲、新舊版本的比較,文件合併等;但對於二進制文件,CVS則明顯力不從心。在CVS 的版本庫中,對於二進制文件的歷史版本,CVS 唯一能做的就是對不同的版本進行獨立的、冗餘的存儲,哪怕版本之間其實只存在微小的差異。舉例而言,一個10M 的二進制文件(照片、圖形文件、機械設計文件、電子設計文件)假如每週修改一次,無論每次修改的大小,一年下來,僅該文件就要消耗500M 以上的存儲空間。而且,客戶端每次獲取該文件的新版本都要消耗10M 的網絡流量。

 

對於目前的開發團隊,無論是軟件開發,Web 站點的開發,手機等電子產品的研發,需要進行版本管理的不僅是源代碼等文本文件,還需要管理需求文檔、設計文檔、測試文檔、用戶手冊,圖形圖像文件,機械/電子設計文件等諸多的二進制文件,CVS 顯然不是一個好的選擇。

 

與CVS 不同,Subversion 採用統一的二進制差異算法(binary differencing algorithm),即對文本文件和二進制文件採用相同的差異比較算法,並以相同的方式在版本庫中進行存儲:每次提交後版本庫中只存儲相對於先前版本的差異,從而可以節省大量的存儲空間。

 

該二進制差異算法不僅應用在版本的存儲上,更爲重要的是,Subversion 對二進制文件與文本文件一視同仁,當客戶端需要獲取新的版本時(如執行svn update),在網絡上只有版本的差異被傳輸,從而大大減少對網絡帶寬的消耗。更多細節參見"七、雙向的差異化-壓縮網絡傳輸"。

 

七、 雙向的差異化-壓縮網絡傳輸

 

如上所述,CVS 對二進制文件不能進行有效的差異化處理。對於文本文件,CVS 僅僅支持單向的差異化傳輸:從CVS 到客戶端的傳輸是差異化的,即執行cvs update 時,只有差異的部分從服務器傳輸到客戶端;而當執行cvs commit 時,無論代碼變化多少,CVS 都需要從客戶端向服務器完整傳輸被修改文件的全部內容,不能只傳輸差異。

 

相反,無論是文本文件還是二進制文件,Subversion 都進行雙向的差異化傳輸,並且差異化內容還要進行壓縮/解壓縮的過程:在服務器端獲取差異顯而易見,與CVS 類似;Subversion 在客戶端獲取差異的祕密在於 — Subversion 在客戶端的工作拷貝中隱含了每個文件的一個"只讀的、乾淨的"副本(該副本隱藏在隱含目錄.svn 裏,通常不可見,該副本還有更多的妙用,參見"十二、更多的本地/離線操作"),通過比較用戶在客戶端的修改和該隱含的副本,Subversion 獲取需要真正傳送到服務器的差異,並對差異進行壓縮後才進行網絡傳輸。

 

對CVS 而言,操作的成本(網絡帶寬消耗是最大的操作成本)與被修改的文件的大小成比例,而與修改本身的大小無關;對Subversion 而言,操作成本只與修改本身的大小成比例,而與被修改的文件的大小無關。因此,與CVS 相比,Subversion 消耗更少的網絡帶寬(以客戶端的存儲空間換取更少的帶寬消耗在目前的計算環境下應該是個相當不錯的選擇!)。Subversion 更加適合基於互聯網(或廣域網)進行協作開發的地理上分佈的團隊 — 版本服務器集中、單一;客戶端廣泛分佈。

 

八、高效、快捷創建分支和基線

 

CVS 和Subversion 都支持分支(branch)和基線(tag),通過分支與合併,可以有效支持大項目的並行開發模式;通過基線管理,可以準確標識一組文件的版本,有效進行軟件發佈管理和必要時的歷史回溯。

 

但CVS 和Subversion 在實現分支和基線的方式上存在很大的不同。CVS 在創建分支的時候,需要對所有進行分支的文件進行依次的操作,因此分支的建立成本(主要是建立分支所需的時間,或消耗的計算資源)與參與分支的文件數量成比例,項目越大,版本庫越大,文件越多,分支的建立成本越高;基線(tag)的建立與此類似。

 

Subversion 的分支和基線是通過執行"拷貝"來建立的:回想一下在沒有引入版本管理工具的時候我們是如何進行所謂的"分支"和"基線"管理的?答案顯然是"拷貝" — 我們通過"拷貝"或"備份"來建立基線;同樣,爲支持多個開發人員可以同時進行開發,我們爲每個開發人員創建一份"拷貝"。由此看來,Subversion 通過"拷貝"來建立分支和基線顯得非常自然,有點"返樸歸真"的意思。

 

由於Subversion 的全局版本號特性,Subversion 中分支或基線的創建過程,或Subversion中的"拷貝"過程,真正的操作是在版本庫中創建一個到某一全局版本號的指針(pointer),不再需要針對衆多的單個文件依次執行操作。因此,該操作的成本爲一個很小的常數,與項目大小,版本庫大小,文件數目的多少無關;並且,分支或基線的建立不需要進行版本的冗餘存儲,新建立的分支或基線基本不佔用版本庫空間,分支的後續存儲空間的開銷也只與修改的大小有關。

 

九、集成Apache Web Server,提供更多的特性

 

Subversion 通過與Apache Web Server 的集成,可以提供基於http/https 協議的版本庫訪問機制,從而支持Subversion 跨越防火牆的安全訪問。除此以外,Subversion 還可以利用更多的Apache 特性,包括但不限於:Apache 豐富的用戶認證機制(包括通過LDAP服務器如Windows Active Directory 服務器的用戶認證),基於目錄路徑的精細粒度的訪問控制,對傳輸的網絡流量進行壓縮/解壓縮,瀏覽版本庫目錄結構等等。

 

十、支持WebDAV

WebDAV(Web-based Distributed Authoring and Versioning)是一種基於 HTTP 1.1 協議的通信協議.它擴展了HTTP 1.1,在GET、POST、HEAD 等幾個HTTP 標準方法以外添加了一些新的方法,使應用程序可直接對Web Server 直接讀寫,並支持寫文件鎖定(Locking)及解鎖(Unlock),還可以支持文件的版本控制。

Microsoft windows2000/XP 及IE, Office 還有Adobe/MicroMedia 的DW 等都支持WebDAV,這又大大增強了Web 應用的價值,以及效能。對於需要大量發佈內容的用戶而言,應用WebDAV 可以降低對CMS 系統的依賴,而且能夠更自由的進行創作。上傳、下載變得輕鬆自如。

Subversion 通過與Apache Web Server 的集成,支持WebDAV 協議,使得業務用戶(business users)或非技術用戶在不安裝任何版本管理客戶端的情況下輕鬆訪問Subversion 版本庫,不改變業務用戶已有使用習慣,支持分佈的業務用戶對文檔的評審、修改並實現版本控制,真正將軟件開發的生命週期從開發/技術團隊擴展到項目的全部干係人(stakeholder),避免通過電子郵件傳遞文檔的混亂與無序、通過Windows 操作系統共享造成的安全漏洞、病毒攻擊、歷史版本被覆蓋或丟失、審計困難等諸多典型問題。

 

十一、更好的衝突標識與處理

 

CVS 和Subversion 都支持通過分支與合併進行並行開發,並可以自動檢測到合併時的衝突(conflicts),並在合併結果中以<<<<<< … >>>>>>標識合併的衝突部分。

在CVS 中,經常會出現由於用戶的疏忽(如,沒有注意到衝突,或沒有完全處理好衝突)而將仍然帶有<<<<<< … >>>>>>衝突標識符號的文件直接進行提交(commit),從而在版本庫中產生垃圾版本。

Subversion 有效解決了CVS 的以上問題:Subversion 記錄並保持文件的衝突狀態,只有當用戶明確執行svn resolved 命令後,該衝突狀態標識才被複位,該文件才能被提交,從而大大減少了將仍然帶有<<<<<< … >>>>>>衝突標識符號的文件直接進行提交的可能性。

 

十二、 更多的本地/離線操作

 

衆所周知,CVS 客戶端的工作拷貝中包含了一個隱含目錄CVS,該目錄中記錄了客戶端需要的一些管理信息;與此類似,Subversion 的客戶端工作拷貝中也包含了一個隱含目錄.svn,該目錄中同樣記錄了客戶端需要的一些管理信息,如版本庫URL,當前訪問版本號等。

與CVS 不同的是,Subversion 的.svn 目錄中還包含了工作拷貝中每一個文件的一個"只讀的、乾淨的"副本。正是由於該副本的存在,使得Subversion 與CVS 相比,可以執行更多的本地/離線操作,即某些操作不需要訪問版本庫服務器,因此不需要存在從客戶端到服務器的網絡鏈接,當然也不消耗任何網絡帶寬,這進一步增強了Subversion 對廣域網的友好支持。

Subversion 的以下命令可以進行離線操作:

svn status - 顯示工作拷貝上的本地修改概況;

svn diff -顯示工作拷貝上的本地修改細節,比較修改前後的內容;

svn revert - 撤銷工作拷貝上的本地修改;

 

十三、 對符號鏈接進行版本管理

 

在Unix 文件系統中,符號鏈接(symbolic links,包括硬鏈接和軟鏈接)是一種重要的文件系統元素。CVS 不能對符號鏈接進行版本管理;Subversion 則可以對符號鏈接進行版本管理。

 

十四、 元數據管理

 

與CVS 相比,Subversion 增加了元數據(metadata)管理機制。即可以對版本庫中的文件或目錄附加任意的"屬性"(property),並記錄屬性的變化歷史,也就是對元數據進行版本管理。一個Subversion 屬性是一個"屬性名稱/屬性值"的二元組,如"BugNumber= 100"就是一個屬性,可以將該屬性附加到版本N 上,以說明版本N 改正了編號爲100的BUG。

Subversion 元數據的目的是提供附件的信息以滿足流程或過程自動化的需要,以增強Subversion 的管理能力和自動化程度。Subversion 自身就通過"屬性"來存儲一些特殊的信息。一個使用Subversion 元數據的例子:可以在一些批處理的腳本程序或Subversion的鉤子程序(hooks)中創建、訪問、修改"屬性"元數據來滿足流程自動化的要求。

十五 VSS CVS 比較

VSS適合小團隊使用,基本的配置管理功能都有。VSS最大的特點就是部署比較簡單,上手比較快。VSS最大的缺點就是安全性問題,目錄共享、文件方式存儲等。當然VSS還只能在Windows下使用。

CVS瞭解過,應該說特點也很鮮明。首先CVS是開源軟件,根據長期的流傳,已經演變了很多版本,適合於不同的平臺。因此,在CVS客戶端上是多種多樣的。其次,CVS的部署稍微複雜點,現對VSS來說,這是其一缺點。最後,CVS在配置管理的理念上,比VSS有所進步。

十六 Vss與Svn 的對比

1. SVN支持重命名,這對 Java開發來說非常重要。

爲了得到更好的代碼,開發中需要經常進行重構,重構就經常涉及到文件的重構名,而重命名中 VSS 中是不被支持的。

2. 開發的時候不一定要鎖定。

一方面導致重構不方便,另一方面,不能離線開發,使用 SVN 就不同,可以帶回家繼續開發,回來後,提交就行了。

3. 多平臺。
可以支持多個平臺下的操作


4. 更好的客戶端支持。
Eclipse 中的 VSS Plugin 不如它的 SVN Plugin 好用。一個在 Windows 下用的 SVN 客戶端 TortoiseSVN 也比 VSS 的客戶端好用(VSS 只有微軟提供的一個 GUI 客戶端)。

5. 更好地與外圍工具集成。

各種各樣的外圍工具(主要是服務器端),滿足多種需要。如果有需要,也可以自己寫插件或管理腳本,開放的架構,允許我們這樣做。

6. 方便。

一個例子:部署應用的時候,以前的做法是找出一個項目中修改過的文件,更新到服務器上去,現在可以在服務器上執行 svn export 命令,把代碼庫中的最新版本導出,完成部署(也可以替換回老版本)。

7. 速度與穩定性看起來都不錯。
學習它的管理、它的工作方式,是值得的。而 VSS 是一個已經被逐漸拋棄的軟件。如果時間不是多得沒處用,那麼就把時間花在最值得花的東西上面。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章