CVS和SVN功能大比拼
本節向大家簡單介紹一下SVN功能和CVS功能比較,主要包括七個方面,在這里和大家分享一下,希望通過本節的學習你對SVN功能和CVS功能的不同之處有所了解,下面是SVN功能和CVS功能的具體介紹。
SVN與CVS的對比——功能性對比
一、SVN包含絕大部分CVS功能
SVN作為CVS的重寫版和改進版,其目標就是作為一個更好的版本控制軟件,取代目前流行的CVS。SVN功能的主要開發人員都是業界知名的CVS專家。SVN支持絕大部分的CVS功能/命令;SVN的命令風格和界面也與CVS非常接近。當然,不同的地方正是對CVS的改進。
二、全局性的版本編號
一個新的版本,并得到一個自增量的版本號N+1,該版本號并不針對某個特定的文件,而是全局性的、針對整個版本庫的。因此,我們可以將SVN的版本庫看作是一個文件系統或文件目錄樹的數組。
從技術的角度來說,在SVN功能中,“文件foo.c的第5版本”這個說法是錯誤的;正確的說法應該是:”文件foo.c在版本庫被修改了5次,即執行5次commit后是什么樣子?”。顯然,在SVN中,版本庫被修改5次后foo.c的內容,和被修改了6次后foo.c的內容很可能完全一樣,因為版本庫的第6次修改很可能只修改了版本庫的其他部分,而并沒有對foo.c的進行修改。相反,在CVS中,文件foo.c的第1.1版本和第1.2版本總是不同的。
SVN的全局性版本編號為SVN帶來了諸多的優勢:如對目錄或文件執行拷貝,無論涉及多少文件,SVN不需要對單個文件依次執行拷貝命令,僅僅需要建立一個指向相應的全局版本號的一個指針即可。
三、目錄的版本控制
CVS只能對文件進行版本控制,不能對目錄進行版本控制,因此CVS沒有任何關于文件“移動”(move)操作的概念。當人為進行文件移動操作時,CVS只能注意到,一個文件在一個位置被刪除了,而在一個新位置創建了另外一個文件。由于它不會連接兩個操作,因此也很容易使文件歷史軌跡丟失。設置CVS存儲庫時,必須非常謹慎地為每個文件選擇準確的位置,因為在設置之后,幾乎就要一直使用這個位置了。
同樣由于CVS不記錄目錄的版本歷史,CVS不支持對文件的“重命名”(rename),人為的對文件進行重命名會使得命名前后的文件失去歷史聯系,而記錄歷史本來是版本管理的主要目的。
還有,CVS不支持對文件的“拷貝”(copy),人為的拷貝對CVS而言,只能看到新的文件的增加,而不能記錄拷貝源文件和目標文件之間的聯系。
綜上所述,缺乏對文件“移動”、“重命名”、“拷貝”的支持的根源在于CVS不能記錄目錄的版本歷史,而這些操作在當前的軟件開發過程中經常發生,這正是SVN被開發并取代CVS的主要原因之一。
SVN將目錄作為一類特殊的文件來處理(事實上,從文件系統的角度來看,目錄確實是一類特殊的文件,當目錄中的子目錄/文件被刪除、重命名、或新的子目錄/文件被創建時,目錄的內容將發生改變)。因此,SVN象記錄普通文件的修改歷史一樣記錄對目錄的修改歷史,當發生文件/目錄的移動、重命名或拷貝操作時,SVN能夠準確記錄操作前后的歷史聯系。同樣,象對文件的不同歷史版本進行比較一樣,SVN支持對目錄的不同歷史版本的比較,清晰展現目錄的變化歷史。
四、原子性提交
從使用者的角度來看,CVS和SVN功能都支持對多個文件修改的批量提交,但二者在實現方式上存在本質的區別。
CVS采用線性、串行的批量提交,即依次地,一個接一個地執行提交,每成功提交一個文件,該文件的一個新的版本即被記錄到版本庫中,提交時用戶提供的日志信息被重復地存儲到每一個被修改的文件的版本歷史中。
CVS串行批量提交模式的弊端在于-當任何原因造成批量操作的中斷時(典型原因包括:網絡中斷、客戶端死機等),版本庫往往處于一個不一致的狀態:原本應該全部入庫的文件只有一部分入庫,很有可能版本庫中的***版本不能順利編譯,更為嚴重的是,隨著其他的用戶執行cvsupdate操作,該不一致性將迅速在開發團隊中擴散,從而嚴重影響團隊的開發效率,并存在質量隱患。另外,假如該批量提交的中斷沒有被及時發現,開發團隊往往要花更多的時間進行軟件調試和排錯。
CVS即使在批量提交不發生中斷時也會造成不一致:假設用戶A啟動一個需要較長時間才能完成的批量提交;與此同時,用戶B執行cvsupdate操作。此時,用戶B很有可能得到一個不一致的更新,即用戶B通過“更新”操作,得到用戶A的部分修改文件。
SVN徹底消除了CVS的以上弊端。無論批量提交包含多少文件修改,只有當全部文件修改都成功入庫,該提交才變得有效,才對其他用戶可見;否則,無論任何原因造成中斷,SVN都會自動執行“回滾”(rollback)操作。換一個說法,SVN保證所有的修改要么全部入庫生效,要么一個也不入庫,即對版本庫不作任何的修改。這就是SVN的原子性提交(atomiccommit)。
由于SVN的原子性提交特性和全局版本編號方式,當提交成功完成時,一個唯一的、新的全局版本編號產生,而提交時用戶提供的日志信息與該新的版本編號關聯,只進行一次存儲(區別于CVS的按文件重復存儲)。
五、支持變更集概念
由于SVN功能中所有提交是原子性的,每次成功提交形成的唯一的全局版本號對應此次批量提交的所有文件修改,也就是說,一個SVN版本號其實對應了一個邏輯上的變更集(changeset),該變更集可能對應于對一個BUG的修復,或者對應于對一個已有功能的改進,或者對應于一個新功能的實現。可以說,變更集是一個軟件開發活動的邏輯結果,該變更集可以通過其對應的版本號在軟件開發的其他過程中(如軟件合并/集成過程,軟件發布管理,變更管理系統,缺陷追蹤系統)被引用。因此,SVN將版本管理從單純的、單個的文件修改的層次通過邏輯上的抽象,上升到更便于理解和交流的開發活動的層次。
六、差異化的二進制文件處理
由于歷史原因,CVS主要是為早期的程序員設計的,CVS能夠有效處理文本文件(或ASCII文件,源代碼文件),可以對文本文件進行差異化的存儲、新舊版本的比較,文件合并等;但對于二進制文件,CVS則明顯力不從心。在CVS的版本庫中,對于二進制文件的歷史版本,CVS唯一能做的就是對不同的版本進行獨立的、冗余的存儲,哪怕版本之間其實只存在微小的差異。舉例而言,一個10M的二進制文件(照片、圖形文件、機械設計文件、電子設計文件)假如每周修改一次,無論每次修改的大小,一年下來,僅該文件就要消耗500M以上的存儲空間。而且,客戶端每次獲取該文件的新版本都要消耗10M的網絡流量。
對于目前的開發團隊,無論是軟件開發,Web站點的開發,手機等電子產品的研發,需要進行版本管理的不僅是源代碼等文本文件,還需要管理需求文檔、設計文檔、測試文檔、用戶手冊,圖形圖像文件,機械/電子設計文件等諸多的二進制文件,CVS顯然不是一個好的選擇。
與CVS不同,SVN采用統一的二進制差異算法(binarydifferencingalgorithm),即對文本文件和二進制文件采用相同的差異比較算法,并以相同的方式在版本庫中進行存儲:每次提交后版本庫中只存儲相對于先前版本的差異,從而可以節省大量的存儲空間。
該二進制差異算法不僅應用在版本的存儲上,更為重要的是,SVN對二進制文件與文本文件一視同仁,當客戶端需要獲取新的版本時(如執行svnupdate),在網絡上只有版本的差異被傳輸,從而大大減少對網絡帶寬的消耗。更多細節參見“七、雙向的差異化-壓縮網絡傳輸”。SVN功能和CVS功能對比介紹中差異化的二進制文件處理講解完畢。
七、雙向的差異化-壓縮網絡傳輸
如上所述,CVS對二進制文件不能進行有效的差異化處理。對于文本文件,CVS功能僅僅支持單向的差異化傳輸:從CVS服務器到客戶端的傳輸是差異化的,即執行cvsupdate時,只有差異的部分從服務器傳輸到客戶端;而當執行cvscommit時,無論代碼變化多少,CVS都需要從客戶端向服務器完整傳輸被修改文件的全部內容,不能只傳輸差異。
相反,無論是文本文件還是二進制文件,SVN都進行雙向的差異化傳輸,并且差異化內容還要進行壓縮/解壓縮的過程:在服務器端獲取差異顯而易見,與CVS類似;SVN在客戶端獲取差異的秘密在于—SVN在客戶端的工作拷貝中隱含了每個文件的一個“只讀的、干凈的”副本(該副本隱藏在隱含目錄.svn里,通常不可見,該副本還有更多的妙用,參見“十二、更多的本地/離線操作”),通過比較用戶在客戶端的修改和該隱含的副本,SVN獲取需要真正傳送到服務器的差異,并對差異進行壓縮后才進行網絡傳輸。
對CVS而言,操作的成本(網絡帶寬消耗是***的操作成本)與被修改的文件的大小成比例,而與修改本身的大小無關;對SVN而言,操作成本只與修改本身的大小成比例,而與被修改的文件的大小無關。因此,與CVS相比,SVN消耗更少的網絡帶寬(以客戶端的存儲空間換取更少的帶寬消耗在目前的計算環境下應該是個相當不錯的選擇!)。SVN更加適合基于互聯網(或廣域網)進行協作開發的地理上分布的團隊——版本服務器集中、單一;客戶端廣泛分布。請期待下節關于SVN功能和CVS功能對比介紹。
【編輯推薦】