分支,標簽,與合并幾乎是所有版本控制系統的基本概念.如果你不熟悉這些功能,我們在這章提供了一個很好
的介紹.如果你非常熟悉了,也能很好的讓你看看Subversion是如何實現這些功能的.
分支是版本控制的一項基本的功能.如果你將要使用Subversion來管理你的數據.這是一個特色你將最終依賴
它.這章要求你已經對Subversion的基本概念比較熟悉.
什么是分支?
假設你需要在你的電腦上維護一份被分離的文檔,一個手冊或是別的什么.某天要求你對同份文檔做一個不同
的修改分離,但分離后他們兩者只有一小部分不同,因此只有輕微的不同.
你將怎么解決這種處境?顯而易見的方法是不是:可以再拷貝這份文檔,然后保存兩個不同的分離版本.當某個
部分要進行修改時,只要寫入對應的文件就可以了.
經常需要對兩個拷貝版本進行同樣的修改.例如:如果發現一個打印錯誤在第一個文件里,這也很可能存在第二
個拷貝文件里.這兩個文件是相同的的.
這就是分支的基本概念,一條基于另外一條開發線存在的分支.并共享在分離之前的日志.一個分支就象一個拷
貝的存在,并從那里離開,并具有自己的歷史.
圖:Figur 4.1. Branches of development
Subversion提供了一些功能來保持文件或目錄分支的平行性.允許通過拷貝數據來創建分支,并記錄與源文件
的關系.也能幫助你將一個分支的修改復制到另外其他的支流上.總的來說,能夠映射出不同的工作拷貝.這樣
就可以在不同的分支上進行工作.
使用分支
圖:Figure 4.2. Starting repository layout
假設Sally與你同時擁有"calc"項目的工作副本,并都有/calc/trunk的工作副本.所有項目相關的文件都
在/calc目錄下,因為你們的團隊已經商定/calc/trunk用于存放開發主線.
此時你被要求完成一個任務就是新增項目的一個基本新特性.這將需要很長的時間來完成,并可能回影響到項
目中的大部分晚間.問題是你不想與Sally有任何沖突,她正在修改項目中的一些存在的小BUG.并依賴于最新發
布的項目版本,這里(/calc/trunk)主線版本是最有效的.如果你提交修改那么肯定會打亂Sally的修改工作.
一種策略就是進入一個空洞:你和Sally在一到兩周內停止共享信息.那就是開始獲取整頓在你工作副本的所有
文件,并不做任何提交一直到你完成工作任務.這個方案存在著很多問題,第一,這樣一來做不安全.很多人喜歡
頻繁的將工作結果上傳到版本庫,已防止工作副本被突發事件破壞引起的后果.第二,不夠容易.如果你在不同
的機器上工作,你就需要手工的將工作副本進行拷貝修改.最后,當你完成你的所有修改后,你將發現很難將你
的工作合并到主線項目的代碼中去.
更好的解決方法就是創,建所有你自己的分支.能頻繁的提交工作在不與其他人的沖突下.也能有選擇性的共享
信息.
創建一個分支
創建一個分支非常簡單-只需要用svn copy命令拷貝項目就可以.Subversion不單支持單文件,也支持整個文件
目錄的分支創建.在此例中,我們要拷貝/calc/trunk文件夾.那么應該把拷貝放在那里呢?任何地方你想要放置
的地方.這里需要提到項目的策略在庫中有/calc/branches目錄空間,并你想要拷貝的目錄名重命名為my-
calc-branch.
有兩種不同的方法來進行拷貝.首先介紹有些麻煩的方法.只是為了讓概念清晰一點.首先,檢出版本庫./calc.
使用svn copy命令拷貝要進行分支的文件目錄.
$ cd bigwc
$ svn copy trunk branches/my-calc-branch
$ svn status
A + branches/my-calc-branch
在這個例自立,拷貝命令遞歸拷貝trunk下的文件到新的工作目錄.branches/my-calc-branch.你可以從svn
status 命令,心得目錄被添加版本庫中.同時注意"+"符號前面的字母A.他表明添加的列表是一些數據的拷貝,
并不是新添加的版本庫的數據.當年提交修改后,版本庫就會創建/calc/branches/my-calc-branch在版本庫中
通過拷貝/calc/trunk,而不是通過工作副本將數據傳送到版本庫.
$ svn commit -m "Creating a private branch of /calc/trunk."
Adding branches/my-calc-branch
Committed revision 341.
現在介紹一種簡單的創建分支的方法,那就是可以通過給svn copy 命令傳入兩個URL路徑來實現.
$ svn copy http://svn.example.com/repos/calc/trunk \
http://svn.example.com/repos/calc/branches/my-calc-branch \
-m "Creating a private branch of /calc/trunk."
Committed revision 341.
從版本庫的角度來看,實際上這兩種方法并無任何區別.注意區別只在與本地客戶端,后者可以立即執行分支任
務,簡單,并不需要你檢出龐大的工作副本.這種方法是最常用的.
圖 4.3. Repository with new copy
廉價的拷貝
Subversion的庫經過特別的設計.當你拷貝一個文件目錄是,你不需要擔心會占用大量的版本庫容量-實際上版
本庫并不會真正的拷貝數據.取而代之的是建立一個新的目錄路口來指向已存在的目錄樹.如果你是UNIX的用
戶,這與磁盤連接的概念是相同的.后面對文件或是目錄的修改也是影響被拷貝文件目錄.任何能夠使用該概念
的地方Subversion都會利用該理念.
這也是為什么聽到廉價拷貝這個詞.我們不需要擔心文件目錄有多大-拷貝的花費都是非常微小的.這種特性也
是每次提交所做的事,每個版本都是一次廉價拷貝.除了很少的一點修改數據進行保存.
當然,這些機制或數據共享對于用戶都是隱藏不可見的.我們能簡單的看到拷貝目錄.主要點就是拷貝是非常廉
價的,無論是時間還是空間.如果你用這種方法拷貝是非常快的.當然可以隨心所欲的進行分支.
使用分支進行工作
現在我們建立了項目的一個份支,我們就可以檢出該分支并開始工作使用它.
$ svn checkout http://svn.example.com/repos/calc/branches/my-calc-branch
A my-calc-branch/Makefile
A my-calc-branch/integer.c
A my-calc-branch/button.c
Checked out revision 341.
這個工作副本并無任何特別之處;只是簡單鏡像了一個庫中項目.當你提交修改后,Sally并不期望當她更新工
作副本的時候看到這些修改.因為她的工作副本是/calc/trunk.
讓我們假設看看一個星期里所發生的事
You make a change to /calc/branches/my-calc-branch/button.c, which creates revision 342.
You make a change to /calc/branches/my-calc-branch/integer.c, which creates revision 343.
Sally makes a change to /calc/trunk/integer.c, which creates revision 344.
現在這里有兩條獨立的開發線
圖Figure 4.4. The branching of one file's history
分支背后的關鍵概念
這里有兩點重要的內容需要在這里記住.第一,Subversion并沒有沖突分支的概念-它只知道怎么去進行拷貝.
當你拷貝一個目錄是,結果就是目錄是一個獨立的分支.你可能回想像一個不同的目錄被建立或被處理.但對于
Subversion只是平常的目錄控制區別只是再擴展一個歷史日志信息.第二,因為這種拷貝機制,Subversion的分
支只是平常的存儲在版本庫中,而不像其他的版本控制系統,分支是真正存儲了目錄文件.
注意,Subversion并不支持不同版本庫之間拷貝也使用映射機制,所以他只能在同版本庫下工作.