- 寫在前面
- 一些相關的概念和原理
- 進行分支開發的最佳實踐
- 合並的分類
- 在 Eclipse 中進行合並操作
- 相關資源
寫在前面
本文是由演講整理而來的,介紹了 SVN 分支與合並的概念、流程和一些實際操作方法,適合對版本控制有基本認識然后想了解 SVN 分支與合並的使用方法的讀者。
對應 SVN 版本最低為 1.5,因為分支、合並的很多功能都是 1.5(release notes ) 才加進來的。
一些相關的概念和原理
- 分支(branch)和標記(tag)對於 SVN 來說就只是副本(copy),沒有任何其它意義。分支和標記的意義是我們人為給予的。
- SVN 的副本是通過"cheap copies "來實現的,建立一個副本就類似 Unix 中創建一個硬鏈接(hard link),空間和時間的消耗都是固定並且很小的,因此不必太過擔心副本太多而導致性能問題。
- SVN 的文件儲存 是通過差異(diff)來實現的,底層儲存方法有兩種:1、Berkeley DB,完整保存一個文件的最新版本(revision),舊版本通過反向差異(reverse diffs)來獲取。2、FSFS,跟 BDB 相反,完整保存一個文件的初始版本,后續版本通過正向差異來獲取。當然,為了避免版本太多而造成性能下降,SVN 還使用了"skip-deltas "來減少需要追溯的版本數。
- SVN 屬性(property )可以附帶在文件、目錄和版本(revision)上。文件和目錄的屬性類似文件內容,會被記錄進版本庫中的,例如每次提交時的注釋,其實就是該版本的一個屬性 svn:log。以"svn:"開頭的屬性是系統預留的,用戶不應該自定義這樣的屬性。
進行分支開發的最佳實踐
- 做分支上做開發的時候,必須定期使分支與主干同步,避免開發完成后合並(merge)回主干時出現嚴重沖突(confict)。
- 進行合並前,處理掉工作副本上的所有本地修改,方便合並失敗時進行回滾(revert)。
- 進行合並時,特別注意 新增/刪除 操作,因為很多沖突都是這類操作引起的。
- 完成一個分支的功能並合並回主干后,拋棄該分支,后續其它功能的開發使用新建的分支。當然,也有辦法繼續使用該分支。
合並的分類
1、從主干到分支
- svn merge [-r M:N] ^/trunk
假設"^/trunk"是主干的 URL,當前目錄為分支的工作副本。該命令同步主干的最新修改到當前工作副本,用於使分支跟主干保持同步。SVN 會通過 svn:mergeinfo 屬性來記錄當前工作副本已經合並過的版本號,然后在每次合並時選擇合適的(eligible)版本進行合並。當然,也可以自己手動指定合並版本M到N的修改。
2、從分支到主干
- svn merge --reintegrate ^/branches/quota
假設"^/branches/quota"是分支的 URL,當前目錄為主干的工作副本。該命令將分支的最新版本(@HEAD)跟主干的最新版本進行比較,將差異實施到當前工作副本,用於將在分支上完成的工作合並回主干。
分支使用 --reintegrate 合並回主干后,如果繼續在該分支上開發,當需要同步主干的修改到分支過來時,默認會包括之前 reintegrate 的修改,而這些修改已經在分支上做過了,所以這樣往往會導致沖突。這也是前面“最佳實踐”中最后一個建議的一個原因。當然,想要使這個分支繼續可用也是可以的,這就需要使用下面這第三種合並。
3、僅記錄的合並
- svn merge -c 25 --record-only ^/trunk
假設當前目錄為分支的工作副本,該命令將主干的版本25標記為已合並到當前工作副本,但並不會進行實質性的合並,這樣下次合並主干到分支時,該版本的修改就會被跳過,避免修改被重復實施導致的沖突。其實這種合並就是改一下 svn:mergeinfo 而已,但直接修改太危險了,所以弄了這樣一個所謂合並來規范操作。
在 Eclipse 中進行合並操作
Subclipse
在 Eclipse 中有兩個比較流行的 SVN 插件:Subclipse 和 Subversive,關於兩者的討論有很多,例如這里 。本文只介紹 Subclipse。
上圖是 Subclipse 進行合並操作時的界面,該圖所對應的操作是:將 trunk 上版本 8 至今的修改同步到工作副本 pearbranch,也就是分支 branches/quake。這里可以發現幾個問題:
- 不能進行自動合並,必須手工指定版本號。
- 不能進行僅記錄的合並
- 不能直接進行 --reintegrate 的合並
CollabNet Merge Client
上述 Subclipse 的不足,應該是因為 Subclipse 默認的合並實現是基於 SVN 1.4 之前的,那時還沒有 svn:mergeinfo、--reintegrate 和 --record-only 呢。要支持這些 1.5 的新特性,可以安裝 CollabNet Merge Client。
CollabNet Merge Client 是 Subclipse 的一個可選功能,其實就是一個增強的、支持新特性的合並實現,如上圖所示,它的優點有:
- 支持合並信息自動跟蹤和自動合並
- 支持 --reintegrate 和 --record-only
- 合並前能對工作副本進行檢查
相關資源
主要是看 Bubble-Up Method 這一節,是 revision 的基本原理。