Subversion 徹底消除了CVS 的以上弊端。無(wú)論批量提交包含多少文件修改,只有當(dāng)全部文件修改都成功入庫(kù),該提交才變得有效,才對(duì)其他用戶可見(jiàn);否則,無(wú)論任何原因造成中斷,Subversion 都會(huì)自動(dòng)執(zhí)行“回滾”(rollback)操作。換一個(gè)說(shuō)法,Subversion 保證所有的修改要么全部入庫(kù)生效,要么一個(gè)也不入庫(kù),即對(duì)版本庫(kù)不作任何的修改。這是Subversion 的原子性提交(atomic commit)。
由于Subversion 的原子性提交特性和全局版本編號(hào)方式,當(dāng)提交成功完成時(shí),一個(gè)的、新的全局版本編號(hào)產(chǎn)生,而提交時(shí)用戶提供的日志信息與該新的版本編號(hào)關(guān)聯(lián),只進(jìn)行一次存儲(chǔ)(區(qū)別于CVS 的按文件重復(fù)存儲(chǔ))。
五、支持變更集概念
由于Subversion 的所有提交是原子性的,每次成功提交形成的的全局版本號(hào)對(duì)應(yīng)此次批量提交的所有文件修改,也是說(shuō),一個(gè)Subversion 版本號(hào)其實(shí)對(duì)應(yīng)了一個(gè)邏輯上的變更集(change set),該變更集可能對(duì)應(yīng)于對(duì)一個(gè)BUG 的修復(fù),或者對(duì)應(yīng)于對(duì)一個(gè)已有功能的改進(jìn),或者對(duì)應(yīng)于一個(gè)新功能的實(shí)現(xiàn)?梢哉f(shuō),變更集是一個(gè)軟件開(kāi)發(fā)活動(dòng)的邏輯結(jié)果,該變更集可以通過(guò)其對(duì)應(yīng)的版本號(hào)在軟件開(kāi)發(fā)的其他過(guò)程中(如軟件合并/集成過(guò)程,軟件發(fā)布管理,變更管理系統(tǒng),缺陷追蹤系統(tǒng))被引用。因此,Subversion 將版本管理從單純的、單個(gè)的文件修改的層次通過(guò)邏輯上的抽象,上升到更便于理解和交流的開(kāi)發(fā)活動(dòng)的層次。
六、差異化的二進(jìn)制文件處理
由于歷史原因,CVS 主要是為早期的程序員設(shè)計(jì)的,CVS 能夠有效處理文本文件(或ASCII文件,源代碼文件),可以對(duì)文本文件進(jìn)行差異化的存儲(chǔ)、新舊版本的比較,文件合并等;但對(duì)于二進(jìn)制文件,CVS 則明顯力不從心。在CVS 的版本庫(kù)中,對(duì)于二進(jìn)制文件的歷史版本,CVS 能做的是對(duì)不同的版本進(jìn)行獨(dú)立的、冗余的存儲(chǔ),哪怕版本之間其實(shí)只存在微小的差異。舉例而言,一個(gè)10M 的二進(jìn)制文件(照片、圖形文件、機(jī)械設(shè)計(jì)文件、電子設(shè)計(jì)文件)假如每周修改一次,無(wú)論每次修改的大小,一年下來(lái),僅該文件要消耗500M 以上的存儲(chǔ)空間。而且,客戶端每次獲取該文件的新版本都要消耗10M 的網(wǎng)絡(luò)流量。
對(duì)于目前的開(kāi)發(fā)團(tuán)隊(duì),無(wú)論是軟件開(kāi)發(fā),Web 站點(diǎn)的開(kāi)發(fā),手機(jī)等電子產(chǎn)品的研發(fā),需要進(jìn)行版本管理的不僅是源代碼等文本文件,還需要管理需求文檔、設(shè)計(jì)文檔、測(cè)試文檔、用戶手冊(cè),圖形圖像文件,機(jī)械/電子設(shè)計(jì)文件等諸多的二進(jìn)制文件,CVS 顯然不是一個(gè)好的選擇。
與CVS 不同,Subversion 采用統(tǒng)一的二進(jìn)制差異算法(binary differencing algorithm),即對(duì)文本文件和二進(jìn)制文件采用相同的差異比較算法,并以相同的方式在版本庫(kù)中進(jìn)行存儲(chǔ):每次提交后版本庫(kù)中只存儲(chǔ)相對(duì)于先前版本的差異,從而可以節(jié)省大量的存儲(chǔ)空間。
該二進(jìn)制差異算法不僅應(yīng)用在版本的存儲(chǔ)上,更為重要的是,Subversion 對(duì)二進(jìn)制文件與文本文件一視同仁,當(dāng)客戶端需要獲取新的版本時(shí)(如執(zhí)行svn update),在網(wǎng)絡(luò)上只有版本的差異被傳輸,從而大大減少對(duì)網(wǎng)絡(luò)帶寬的消耗。更多細(xì)節(jié)參見(jiàn)“七、雙向的差異化-壓縮網(wǎng)絡(luò)傳輸”。
七、 雙向的差異化-壓縮網(wǎng)絡(luò)傳輸
如上所述,CVS 對(duì)二進(jìn)制文件不能進(jìn)行有效的差異化處理。對(duì)于文本文件,CVS 僅僅支持單向的差異化傳輸:從CVS 服務(wù)器到客戶端的傳輸是差異化的,即執(zhí)行cvs update 時(shí),只有差異的部分從服務(wù)器傳輸?shù)娇蛻舳;而?dāng)執(zhí)行cvs commit 時(shí),無(wú)論代碼變化多少,CVS 都需要從客戶端向服務(wù)器完整傳輸被修改文件的全部?jī)?nèi)容,不能只傳輸差異。
相反,無(wú)論是文本文件還是二進(jìn)制文件,Subversion 都進(jìn)行雙向的差異化傳輸,并且差異化內(nèi)容還要進(jìn)行壓縮/解壓縮的過(guò)程:在服務(wù)器端獲取差異顯而易見(jiàn),與CVS 類似;Subversion 在客戶端獲取差異的秘密在于 — Subversion 在客戶端的工作拷貝中隱含了每個(gè)文件的一個(gè)“只讀的、干凈的”副本(該副本隱藏在隱含目錄.svn 里,通常不可見(jiàn),該副本還有更多的妙用,參見(jiàn)“十二、更多的本地/離線操作”),通過(guò)比較用戶在客戶端的修改和該隱含的副本,Subversion 獲取需要真正傳送到服務(wù)器的差異,并對(duì)差異進(jìn)行壓縮后才進(jìn)行網(wǎng)絡(luò)傳輸。
對(duì)CVS 而言,操作的成本(網(wǎng)絡(luò)帶寬消耗是大的操作成本)與被修改的文件的大小成比例,而與修改本身的大小無(wú)關(guān);對(duì)Subversion 而言,操作成本只與修改本身的大小成比例,而與被修改的文件的大小無(wú)關(guān)。因此,與CVS 相比,Subversion 消耗更少的網(wǎng)絡(luò)帶寬(以客戶端的存儲(chǔ)空間換取更少的帶寬消耗在目前的計(jì)算環(huán)境下應(yīng)該是個(gè)相當(dāng)不錯(cuò)的選擇。ubversion 更加適合基于互聯(lián)網(wǎng)(或廣域網(wǎng))進(jìn)行協(xié)作開(kāi)發(fā)的地理上分布的團(tuán)隊(duì) — 版本服務(wù)器集中、單一;客戶端廣泛分布。
八、高效、快捷創(chuàng)建分支和基線
CVS 和Subversion 都支持分支(branch)和基線(tag),通過(guò)分支與合并,可以有效支持大項(xiàng)目的并行開(kāi)發(fā)模式;通過(guò)基線管理,可以準(zhǔn)確標(biāo)識(shí)一組文件的版本,有效進(jìn)行軟件發(fā)布管理和必要時(shí)的歷史回溯。
但CVS 和Subversion 在實(shí)現(xiàn)分支和基線的方式上存在很大的不同。CVS 在創(chuàng)建分支的時(shí)候,需要對(duì)所有進(jìn)行分支的文件進(jìn)行依次的操作,因此分支的建立成本(主要是建立分支所需的時(shí)間,或消耗的計(jì)算資源)與參與分支的文件數(shù)量成比例,項(xiàng)目越大,版本庫(kù)越大,文件越多,分支的建立成本越高;基線(tag)的建立與此類似。
Subversion 的分支和基線是通過(guò)執(zhí)行“拷貝”來(lái)建立的:回想一下在沒(méi)有引入版本管理工具的時(shí)候我們是如何進(jìn)行所謂的“分支”和“基線”管理的?答案顯然是“拷貝” — 我們通過(guò)“拷貝”或“備份”來(lái)建立基線;同樣,為支持多個(gè)開(kāi)發(fā)人員可以同時(shí)進(jìn)行開(kāi)發(fā),我們?yōu)槊總(gè)開(kāi)發(fā)人員創(chuàng)建一份“拷貝”。由此看來(lái),Subversion 通過(guò)“拷貝”來(lái)建立分支和基線顯得非常自然,有點(diǎn)“返樸歸真”的意思。
由于Subversion 的全局版本號(hào)特性,Subversion 中分支或基線的創(chuàng)建過(guò)程,或Subversion中的“拷貝”過(guò)程,真正的操作是在版本庫(kù)中創(chuàng)建一個(gè)到某一全局版本號(hào)的指針(pointer),不再需要針對(duì)眾多的單個(gè)文件依次執(zhí)行操作。因此,該操作的成本為一個(gè)很小的常數(shù),與項(xiàng)目大小,版本庫(kù)大小,文件數(shù)目的多少無(wú)關(guān);并且,分支或基線的建立不需要進(jìn)行版本的冗余存儲(chǔ),新建立的分支或基線基本不占用版本庫(kù)空間,分支的后續(xù)存儲(chǔ)空間的開(kāi)銷也只與修改的大小有關(guān)。
九、集成Apache Web Server,提供更多的特性
Subversion 通過(guò)與Apache Web Server 的集成,可以提供基于http/https 協(xié)議的版本庫(kù)訪問(wèn)機(jī)制,從而支持Subversion 跨越防火墻的安全訪問(wèn)。除此以外,Subversion 還可以利用更多的Apache 特性,包括但不限于:Apache 豐富的用戶認(rèn)證機(jī)制(包括通過(guò)LDAP服務(wù)器如Windows Active Directory 服務(wù)器的用戶認(rèn)證),基于目錄路徑的精細(xì)粒度的訪問(wèn)控制,對(duì)傳輸?shù)木W(wǎng)絡(luò)流量進(jìn)行壓縮/解壓縮,瀏覽版本庫(kù)目錄結(jié)構(gòu)等等。