簡介 Subversion (簡稱
SVN )是近年來崛起的版本管理軟體系統,是
CVS 的接班人。目前,絕大多數
開源軟體 都使用SVN作為代碼版本管理軟體。
Subversion是一個版本控制系統,相對於的
RCS 、CVS,採用了分支管理系統,它的設計目標就是取代CVS。網際網路上免費的版本控制服務多基於Subversion。
Subversion的版本庫可以通過網路訪問,從而使用戶可以在不同的電腦上進行操作。從某種程度上來說,允許用戶在各自的空間裡修改和管理同一組數據可以促進團隊協作。因為修改不再是單線進行(單線進行也就是必須一個一個進行),開發進度會進展迅速。此外,由於所有的工作都已版本化,也就不必擔心由於錯誤的更改而影響
軟體質量 —如果出現不正確的更改,只要撤銷那一次更改操作即可。某些版本控制系統本身也是軟體配置管理系統(
SCM ),這種系統經過精巧的設計,專門用來管理
原始碼 樹,並且具備許多與軟體開發有關的特性——比如對程式語言的支持或者提供程式構建工具。不過Subversion並不是這樣的系統,它是一個通用系統,可以管理任何類型的檔案集。
歷史 早在2000年,
CollabNet 就開始尋找
CVS 替代產品的開發人員。CollabNet提供了一個名為CollabNet企業版(CEE)的協作軟體套件。這個軟體套件的一個組成部分就是版本控制系統。儘管CEE在最初採用了CVS作為其版本控制系統,但是CVS的局限性從一開始就很明顯,CollabNet知道遲早要找到一個更好的替代品。遺憾的是,CVS已經成為開源世界事實上的標準,很大程度上是因為沒有更好的替代品,至少是沒有可以自由使用的替代品,所以CollabNet決定從頭編寫一個新的版本控制系統,這個系統保留CVS的基本思想,但是要修正其中錯誤和不合理的特性。
2000年2月,他們聯繫到OpenSource Development with CVS(Coriolis,1999)的作者Karl Fogel,並且詢問他是否希望為這個新項目工作。巧合的是,當時Karl正在與朋友Jim Blandy討論設計一個新的版本控制系統,1995年時,他們兩人曾經開辦了一個提供CVS支持的公司CyclicSoftware,儘管他們最終賣掉了公司,但還是天天使用CVS進行日常工作。使用CVS時的挫折促使Jim認真的思考如何管理版本化的數據,並且他當時不僅使用了“Subversion”這個名字,並且已經完成了Subversion版本庫的最初設計,所以當CollabNet提出邀請的時候,Karl馬上同意為這個項目工作,同時Jim也找到了他的僱主(
RedHat 軟體公司)允許他到這個項目工作,並且沒有限定最終的期限。CollabNet僱傭了Karl和BenCollinsSussman,詳細設計工作從三月開始,在Behlendorf、CollabNet、JasonRobbins和GregStein(當時是一個獨立開發者,活躍在WebDAV/DeltaV系統規範制訂工作中)恰到好處的激勵下,Subversion很快吸引了許多活躍的開發者,結果是許多對CVS有過失望經歷的人很樂於為這個項目做些事情。
最初的設計小組設定了簡單的開發目標。他們不想在版本控制方法學中開墾處女地,他們只是希望修正CVS。他們決定Subversion應符合CVS的特性,並保留相同的開發模型,但不再重複CVS的一些顯著缺陷。儘管Subversion並不需要成為CVS的完全替代品,但它應該與CVS保持足夠的相似性,以使CVS用戶可以輕鬆的轉移到Subversion上。
經過14個月的編碼,2001年8月31日,Subversion能夠“自己管理自己”了,開發者停止使用CVS保存Subversion的代碼,而使用Subversion本身。
雖然CollabNet啟動了這個項目,並且一直提供了大量的工作支持(它為一些全職的Subversion開發者提供薪水),但Subversion像其它許多
開源項目 一樣,被鬆散的、透明的規則管理著,這樣的規則激勵著知識界的精英們。CollabNet的
著作權許可 完全符合
Debian 的
自由軟體 方針。也就是說,任何人都可以根據自己的意願自由的下載、修改和重新發布Subversion,不需要CollabNet或其他人的授權。
功能 ·包含絕大部分CVS的功能
CVS是最基本的版本控制系統。Subversion包含了CVS的大部分功能,並且針對有些功能還稍加改進。
·目錄的 版本化
Subversion將目錄名以版本號的形式體現。
·基於版本的複製,刪除和重命名
無論複製、刪除還是重命名,都會被打上版本號,儘管這聽上去有些奇怪。
·自由的版本化元數據操作
Subversion允許任何
元數據 附加在檔案或目錄中。這些屬性是鍵/值對,並且被版本化。Subversion也提供對修訂版附加任何鍵/值屬性的方法,這些屬性不會被版本化,因為他們會自動將元數據附加到版本空間中,但他們可以隨時被更改。
·混合追蹤
Subversion 1.5開始加入了混合追蹤功能。
·檔案鎖
支持檔案鎖定,當多個用戶試圖編輯同一個檔案時會收到警告。
使用基於HTTP的WebDAV/DeltaV協定進行網路通信,而Apache
網路伺服器 提供
網路存儲 的站點服務。
·可執行的標籤
當一個檔案是可執行的時候,Subversion會提示,並且當這個可執行的檔案被放在版本控制中時,Subversion會防止該程式檢查其他目錄。
恢復到一個較早的版本 ·獨立進程模式
Subversion可以運行在獨立模式下
Subversion提供一個工具,SVNsync, 用於同步主伺服器上的 檔案到一個子
存儲伺服器 上,並且標為唯讀的屬性
使用情況 雖然在 2006年 時 Subversion 的使用族群仍然遠少於傳統的 CVS,但已經有許多
開放源碼 團體決定將 CVS 轉換為 Subversion。已經轉換使用 Subversion 的包括了
FreeBSD 、Apache Software Foundation、
KDE 、
GNOME 、
GCC 、
Python 、
Samba 、
Mono 以及許多團體。許多開發團隊換用 Subversion 是因為 Trac、SourceForge、CollabNet、
CodeBeamer 等專案協同作業軟體以及
Eclipse 、
NetBeans 等IDE提供 Subversion的資源整合。 除此之外,一些自由軟體開發的協作網如
SourceForge .net除了提供 CVS 外,現在也提供專案開發者使用 Subversion 作為源碼管理系統, JavaForge、
Google Code以及 BountySource則以 Subversion 作為官方的源碼管理系統。
客戶端使用
2009年,絕大多數CVS服務已經改用SVN。CVS已經停止維護。
客戶端 Subversion的客戶端有兩類,一類是WebSVN等基於Web的,一種是以
TortoiseSVN 為代表的客戶端軟體。前者需要Web伺服器的支持,後者需要用戶在本地安裝客戶端,兩種都有免費開源軟體供使用。
安裝完畢後截圖 伺服器 SVN 伺服器有2種運行方式:獨立伺服器和藉助Apache。2種方式各有利弊。
SVN存儲版本數據也有2種方式:
Berkeley DB 和
FSFS 。因為Berkeley DB方式在伺服器中斷時,有可能鎖住數據,所以還是FSFS方式更安全一點。
優點 在SVN之前,CVS(Concurrent Version System:協同版本控制系統)是使用最廣泛的版本管理軟體,伺服器上保存所有的開發項目,開發者們通過伺服器上的已分享資料夾,共同開發同一個項目,達到追蹤所有的工作進度,而伺服器上也會保存
歷史版本 信息,以方便開發者排錯。
SVN與CVS對比的優點如下:
* 統一的版本號。CVS是對每個檔案順序編排
版本號 ,在某一時間各檔案的版
本號各不相同。而Subversion下,任何一次提交都會對所有檔案增加到同一個新版本號,即使是提交並不涉及的檔案。所以,各檔案在某任意時間的版本號是相同的。版本號相同的檔案構成軟體的一個版本。
基本概念圖 * 原子提交。一次提交不管是單個還是多個檔案,都是作為一個整體提交的。在這當中發生的意外例如傳輸中斷,不會引起資料庫的不完整和數據損壞。
* 重命名、複製、刪除檔案等動作都保存在版本歷史記錄當中。
* 對於
二進制檔案 ,使用了節省空間的保存方法(簡單的理解,就是只保存和上一版本不同之處)。
* 目錄也有版本歷史。整個目錄樹可以被移動或者複製,操作很簡單,而且能夠保留全部
版本記錄 。
* 分支的開銷非常小。
* 最佳化過的資料庫訪問,使得一些操作不必訪問資料庫就可以做到,這樣減少了很多不必要的和資料庫主機之間的網路流量。
不足 只能設定目錄的訪問許可權,無法設定單個檔案的訪問許可權。
若用戶有設定單個檔案的訪問許可權的需求,國內有單位可提供基於開源Subversion的擴展版本,見參考資料。
另外,Subversion的官方版本不支持
NTFS檔案系統 的擴展屬性,NTFS的擴充屬性(安全屬性、附加數據流(可選數據流)、加密數據流等)在提交、檢出、導入、導出等操作過程中會丟失。
現在國內有提供支持NTFS擴展屬性的擴充版Subversion、tSVN, 即NTFS的擴充屬性(安全屬性、附加數據流(可選數據流)、加密數據流等)可和檔案一起被提交、檢出、導入、導出。見參考資料。
企業級 Subversion Multisite
對於企業級套用,Subversion還有其先天不足,比如對於多個地點的並行開發。目前Subversion multisite,實現異地對等伺服器自動同步,支持並行開發以及
異地備份 。
基於Subversion的ALM平台——UberSVN
ALM(Application Lifecycle Management)是軟體配置管理的未來趨勢,各種軟體版本工具包括Subversion都要集成到其中。目前UberSVN是唯一的以Subversion為基礎構建的ALM平台,並實現了協同開發以及社交化編碼。
是客戶端還是伺服器
Subversion代表的是代碼
版本管理 的一種標準,沒有嚴格區分其到底是伺服器還是客戶端,同樣提供二者的功能。
特性 Subversion支持:
版本化的目錄
CVS只能跟蹤單個檔案的變更歷史,但是Subversion實現的“虛擬”版本化檔案系統則可以跟蹤目錄樹的變更。在Subversion中,檔案和目錄都是版本化的。
真實的版本歷史
由於只能跟蹤單個檔案的變更,CVS無法支持如檔案拷貝和改名這些常見的操作——這些操作改變了目錄的內容。同樣,在CVS中,一個目錄下的檔案只要名字相同即擁有相同的歷史,即使這些同名檔案在歷史上毫無關係。而在Subversion中,可以對檔案或目錄進行增加、拷貝和改名操作,也解決了同名而無關的檔案之間的歷史聯繫問題。
原子提交
一系列相關的更改,要么全部提交到版本庫,要么一個也不提交。這樣用戶就可以將相關的更改組成一個邏輯整體,防止出現只有部分修改提交到版本庫的情況。
版本化的元數據
每一個檔案和目錄都有自己的一組屬性——鍵和值,可以根據需要建立並存儲任何鍵/值對。與檔案本身的內容一樣,屬性也在版本控制之下。
可選的網路層
Subversion在版本庫訪問的實現上具有較高的抽象程度,利於人們實現新的網路訪問機制。Subversion可以作為一個擴展模組嵌入到Apache之中,這種方式在穩定性和互動性方面有很大的優勢,可以直接使用伺服器的成熟技術——
認證 、
授權 和傳輸壓縮等。此外,Subversion自身也實現了一個輕型的、可獨立運行的
伺服器軟體 ,這個伺服器使用了一個自定義協定,可以輕鬆地使用
SSH 封裝。
一致的數據操作
Subversion用一個二進制差異算法描述檔案的變化,對於文本(可讀)和二進制(不可讀)檔案其操作方式是一致的,兩種類型的檔案壓縮存儲在版本庫中,而差異信息則在網路上雙向傳遞。
在Subversion中,分支與標籤操作的開銷與工程的大小無關。Subversion的分支和標籤操作只是一種類似於
硬連結 的機制拷貝整個工程,因而這些操作通常只會花費很少且相對固定的時間。
可修改性
Subversion沒有歷史負擔,它以一系列優質的共享C
程式庫 的方式實現,具有定義良好的API,這使得Subversion非常容易維護,和其它語言的互操作性很強。
架構 如圖給出了Subversion設計總體上的“俯視圖”。圖中的一端是保存所有版本數據的Subversion版本庫,另一端是Subvesion的客戶程式,管理著所有版本數據的本地
映射 (稱為“工作拷貝”),在這兩極之間是各種各樣的版本庫訪問(RA)層,某些使用電腦網路通過網路伺服器訪問版本庫,某些則繞過網路伺服器直接訪問版本庫。
Subversion的架構
組件 安裝好的Subversion由幾個部分組成,下面將簡單的介紹一下這些組件。下文的描述或許過於簡略,不易理解,但不用擔心,本書後面的章節中會用更多的內容來詳細闡述這些組件。
SVN
命令行客戶端程式。
SVNversion
此工具用來顯示工作拷貝的狀態(用術語來說,就是當前項目的修訂版本)。
SVNlook
直接查看Subversion版本庫的工具。
SVNadmin
建立、調整和修復Subversion版本庫的工具。
SVNdumpfilter
過濾Subversion版本庫轉儲數據流的工具。
mod_dav_SVN
ApacheHTTP伺服器的一個
外掛程式 ,使版本庫可以通過網路訪問。
SVNserve
一個單獨運行的伺服器程式,可以作為
守護進程 或由SSH調用,這是另一種使版本庫,可以通過網路訪問的方式。
SVNsync
一個通過網路增加鏡像版本庫的程式。
基本概念 先為那些不熟悉
版本控制 技術的入門者提供一個簡單扼要、非系統的介紹,這裡將從版本控制的基本概念開始,隨後闡述Subversion的獨特理念,並演示一些使用Subversion的例子。
下面以分享程式原始碼作為例子,但是記住Subversion可以管理任何類型的檔案集——它並非是程式設計師專用的。
版本庫 Subversion是一個“集中式”的信息共享系統。版本庫是Subversion的核心部分,是數據的中央倉庫。版本庫以典型的檔案和目錄結構形式的檔案系統樹來保存信息。任意數量的客戶端連線到Subversion版本庫,讀取、修改這些檔案。客戶端通過寫數據將信息分享給其他人,通過讀取數據獲取別人共享的信息。圖“一個典型的客戶/伺服器系統”展示了這種系統:
Subversion聽起來跟一般的檔案伺服器沒什麼不同。事實上,Subversion的版本庫的確是一種
檔案伺服器 ,但不是“一般”的檔案伺服器。Subversion版本庫的特別之處在於,它會記錄每一次改變:每個檔案的改變,甚至是目錄樹本身的改變,例如檔案和目錄的添加、刪除和重新組織。
一般情況下,客戶端從版本庫中獲取的數據是檔案系統樹中的最新數據,但是客戶端也具備查看檔案系統樹以前任何一個狀態的能力。舉個例子,客戶端有時會對一些歷史性問題感興趣,比如“上星期三時的目錄結構是什麼樣的?”或者“誰最後一個修改了這個檔案,都修改了什麼?”這些都是版本控制系統的核心問題(設計用來記錄和跟蹤數據變化的系統)。
版本模型 版本控制系統的核心任務是實現協作編輯和數據共享。但是不同的系統使用不同的策略實現這個目的。有理由去理解這些策略的區別,首先,如果遇到了其他類似Subversion的系統,可以幫助比較現有的版本控制系統;此外,可以幫助更有效的使用Subversion,因為Subversion本身支持不同的工作方式。
檔案共享 所有的版本控制系統都需要解決這樣一個基礎問題:怎樣讓系統允許用戶共享信息,而不會讓他們因意外而互相干擾?在版本庫里意外覆蓋別人的更改非常容易。
注意事項 考慮“需要避免的問題”的情景,有兩個共同工作者,Harry和Sally,他們想同時編輯版本庫里的同一個檔案,如果首先Harry保存它的修改,過了一會,Sally可能湊巧用自己的版本覆蓋了這些檔案,Harry的更改不會永遠消失(因為系統記錄了每次修改),但Harry所有的修改不會出現在Sally新版本的檔案中,所以Harry的工作還是丟失了,至少是從最新的版本中丟失了,而且可能是意外的,這是要明確避免的情況!
鎖定-修改-解鎖方案
許多版本控制系統使用鎖定-修改-解鎖機制解決這種問題,在這樣的模型里,在一個時間段里版本庫的一個檔案只允許被一個人修改。首先在修改之前,Harry要“鎖定”
住這個檔案,鎖定很像是從圖書館借一本書,如果Harry鎖住這個檔案,Sally不能做任何修改,如果Sally想請求得到一個鎖,版本庫會拒絕這個請求。在Harry結束編輯並且放開這個鎖之前,她只可以閱讀檔案。Harry解鎖後,就要換班了,Sally得到自己的輪換位置,鎖定並且開始編輯這個檔案。圖1.3“鎖定-修改-解鎖方案”描述了這樣的解決方案。
解決方案圖 鎖定-修改-解鎖模型有一點問題就是限制太多,經常會成為用戶的障礙:
1.鎖定可能導致管理問題。有時候Harry會鎖住檔案然後忘了此事,這就是說Sally一直等待解鎖來編輯這些檔案,她在這裡僵住了。然後Harry去旅行了,現在Sally只好去找管理員放開鎖,這種情況會導致不必要的耽擱和時間浪費。
2.鎖定可能導致不必要的線性化開發。如果Harry編輯一個檔案的開始,Sally想編輯同一個檔案的結尾,這種修改不會衝突,構想修改可以正確的合併到一起,他們可以輕鬆的並行工作而沒有太多的壞處,沒有必要讓他們輪流工作。
3.鎖定可能導致錯誤的安全狀態。假設Harry鎖定和編輯一個檔案A,同時Sally鎖定並編輯檔案B,如果A和B互相依賴,這種變化是必須同時作的,這樣A和B不能正確的工作了,鎖定機制對防止此類問題將無能為力—從而產生了一種處於安全狀態的假相。很容易想像Harry和Sally都以為自己鎖住了檔案,而且從一個安全,孤立的情況開始工作,因而沒有儘早發現他們不匹配的修改。鎖定經常成為真正交流的替代品
拷貝-修改-合併方案
Subversion、CVS和一些版本控制系統使用拷貝-修改-合併模型,在這種模型里,每一個客戶聯繫項目版本庫建立一個個人工作拷貝—版本庫中檔案和目錄的本地映射。用戶並行工作,修改各自的工作拷貝,最終,各個私有的拷貝合併在一起,成為最終的版本,這種系統通常可以輔助合併操作,但是最終要靠人工去確定正誤。
下面是一個例子,Harry和Sally為同一個項目各自建立了一個工作拷貝,工作是並行的,修改了同一個檔案A,Sally首先保存修改到版本庫,當Harry想去提交修改的時候,版本庫提示檔案A已經過期,換句話說,A在他上次更新之後已經更改了,所以當他通過客戶端請求合併版本庫和他的工作拷貝之後,碰巧Sally的修改和他的不衝突,所以一旦他把所有的修改集成到一起,他可以將工作拷貝保存到版本庫。
但是如果Sally和Harry的修改交疊了怎么辦?這種情況叫做衝突,這通常不是個大問題,當Harry告訴他的客戶端去合併版本庫的最新修改到自己的工作拷貝時,他的檔案A就會處於衝突狀態,他可以看到一對衝突的修改集,並手工的選擇保留一組修改。需要注意的是軟體不能自動的解決衝突,只有人可以理解並作出智慧型的選擇,一旦Harry手工地解決了衝突——也許需要與Sally討論,它可以安全地把合併的檔案保存到版本庫。
拷貝-修改-合併模型感覺有一點混亂,但在實踐中,通常運行的很平穩,用戶可以並行的工作,不必等待別人,當工作在同一個檔案上時,也很少會有交疊發生,衝突並不頻繁,處理衝突的時間遠比等待解鎖花費的時間少。
最後,一切都要歸結到一條重要的因素:用戶交流。當用戶交流貧乏,語法和語義的衝突就會增加,沒有系統可以強制用戶進行完美的交流,沒有系統可以檢測語義上的衝突,所以沒有任何證據能夠承諾鎖定系統就可以防止衝突,實踐中,鎖定除了約束了生產力,並沒有做什麼事。
什麼時候鎖定是必需的
鎖定-修改-解鎖模型被認為不利於協作,但有時候鎖定會更好。
拷貝-修改-合併模型假定檔案是可以根據上下文合併的,就是版本庫的檔案主要是以行為基礎的文本檔案(例如程式原始碼)。但對於二進制格式,例如藝術品或聲音,在這種情況下,十分有必要讓用戶輪流修改檔案,如果沒有線性的訪問,有些人的許多工作就最終要被放棄。
儘管Subversion一直主要是一個拷貝-修改-合併系統,但是它也意識到了需要鎖定一些檔案,並且提供這種鎖定機制,這個特性的討論可以見“鎖定”一節。
實例研究 MartinFowler使用SVN
一兩年前,我工作生涯的一個重要方面發生了變化,那之前我一直只在一台電腦上工作(更確切地說是只用一塊硬碟),所有工作檔案都保存在我的筆記本硬碟里。如果我要用另外一台桌面電腦,就通過
檔案共享 操作那些檔案。
自從去年我買了
PowerBook 事情就變了,現在我經常轉戰於三台機器:MacPowerBook、
Windows 筆記本、
Ubuntu 桌面。這就意味著我得保持多台機器上的東西都是最新的——至少我的工作檔案都要保持最新。有了多台桌面電腦,我主要的Email服務從
POP 轉到了
IMAP ,這給我帶來巨大的便利——儘管它有時“打打隔”,但我敢說IMAP在我的多台機器上跑得很好(我用
Thunderbird 做客戶端)。
我大部分工作檔案都被Subversion管理起來了,每當切換機器時我就提交(commit)工作目錄,再到新機器上更新(update)。一切都同步得好好的,還全面享受了版本管理服務。
不過,也有一些東西同步起來沒我想要的那么方便。地址簿就很難直接同步,Thunderbird總固執地把它們放到一個特定的地方,Subversion檢查不到。更倒霉的是,地址簿是二進制檔案,難以合併(merge),這很煩人,但Thunderbird用文本檔案來處理Email,這一點兒挺招人喜歡的,當IMAP打嗝時我也不難處理。另外,與
PDA 同步也很難纏,最後我還是找到個不賴的辦法把所有聯繫人和日程表信息在三台機器上都同步好了。再者就是news聚合工具,它們之間可以通過
OPML 共享
feeds (至少理論上如此),但不能記錄下哪些我讀過了哪些還沒讀。
檔案儘量採用文本格式,這樣做好處很多。我所有寫作都是用
XML ,要同步寫的東西只需要一個文本編輯器。但圖表就成問題了,我還沒找到一個在所有平台上都能用的東西,不過,搭起多台桌面有一個好處,所有專用於一個系統的軟體我也能用了。
版本發布 2012年02月21日,Subversion Access control 4.1 引入更為敏捷靈活的授權方式。
2012年03月09日,Apache Subversion 1.7.4 發布。
2012年05月19日,Apache Subversion 1.7.5 發布。
2012年08月16日,Apache Subversion 1.7.6 發布。
2012年10月09日,Apache Subversion 1.7.7 發布。