The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

講解 Subversion 分支與合併:以 TortoiseSVN 為例

在實務的版本控管情境中,套用分支與合併應該是最方便不過的了,會用的人可以得到許多版本控管的好處,但不會用的人卻會因為不理解而害怕使用它,由於 Subversion 1.5 開始新增了 Merge Tracking 功能,可有效降低維護分支的負擔,所以能學會分支與合併的技巧對整個版本管理流程來說會有非常大的幫助,今天我就來講解幾個利用 TortoiseSVN 實際的操作分支與合併的例子。

如下圖是一個很常見的分支示意圖,當你想在 trunk 發展一個新功能時,你可以透過 svn copy 的方式將整個 /calc/trunk 廉價複製/calc/branches/my-calc-branch,當 /calc/branches/my-calc-branch 分支完成所有新功能開發後,再將所有變更一次合併回 /calc/trunk 開發主線。

我講的 svn copy 其實就是對應到 TortoiseSVN 的 Branch/tag 功能

 

使用時應注意以下:

  1. 你要廉價複製的來源路徑
  2. 你要廉價複製的目的路徑 (「複製」就等同於「分支」,這是 SVN 附加上去的意義 )
  3. 寫下你為什麼要建立這個分支、用途是什麼,這訊息可以給團隊成員或版本經理看
  4. 我們可以在執行 Copy (Branch/tag) 的同時順便將你的「工作目錄」切換至「分支的路徑」

這時我們可以看一下 trunk 這個目錄的屬性,並切換至 Subversion 頁籤,你會發現該「工作目錄」所對應到的 Subversion 路徑已經變更到 /calc/branches/my-calc-branch 了。

但為了怕初學者混淆,我還是先將 /calc/trunk 切換回原本的 SVN 路徑:

這裡有幾點注意:

  1. 這裡是你的「工作目錄」(Working Copy)
  2. 這裡才是你要將「工作目錄」切換到的 SVN 路徑,也就是將 /calc/branches/my-calc-branch 切換至 /calc/trunk 路徑

這時你便可以開始在 /calc/branches/my-calc-branch 發展你這次想要新增的功能,且不會影響到其他團隊成員正在發展或維護的 /calc/trunk 開發主線。

也許過了一段時間,原本的 /calc/trunk 開發主線可能已經有其他團隊成員陸續修正了一些 Bugs,但這時你的分支 /calc/branches/my-calc-branch 就可以直接套用 開發主線 ( /calc/trunk ) 的更新,除了避免重複的工作外 (重複除錯),也可以避免版本的衝突發生,因為兩個人改同一個已知的 Bug 可能會因為用不同方法除錯或命名的方式不一致而發生衝突。

經常將 開發主線 ( /calc/trunk ) 的變更透過 svn merge 合併至 分支線路 ( /calc/branches/my-calc-branch ) 是一個非常好的習慣,這樣才不會讓你因為脫離 開發主線(trunk) 過久而導致將 分支線路 ( /calc/branches/my-calc-branch ) 合併回 開發主線 ( /calc/trunk ) 時發生許多版本衝突。

 

開發主線 ( /calc/trunk ) 合併至 分支線路 ( /calc/branches/my-calc-branch ) 通常選第 1 個,也就是 [Merge a range of revisions]

在 Merge 的視窗有以下注意事項:

  1. 設定要合併的來源,由於我們打算從 開發主線 ( /calc/trunk ) 合併分支這段時間所產生的變更至 分支線路 ( /calc/branches/my-calc-branch ),所以合併的來源要選擇 /calc/trunk 才對!
  2. 合併的結果會直接與目前「工作目錄」(Working Copy) 做比對,並修改目前工作目錄中的所有檔案。因此建議在做合併之前可以將所有尚未 commit 的檔案先 commit 到版本庫,避免不必要的衝突事件發生。

在正式進行合併(Merge)之前,建議先執行 Test merge 看看是否會發生什麼事!

若無異狀則可直接按下 [Merge] 按鈕進行合併動作,這時從 開發主線 ( /calc/trunk ) 分支出來的到目前工作目錄的版本就會做個比較,然後直接套用變更到你現有的檔案、目錄或屬性裡。

在合併之後如果沒有發生衝突,不代表真的沒衝突,所以必須再次對原始碼做出驗證後才能 commit 進版本庫,建議可參考以下流程:

  1. 將專案進行建置(Build)
  2. 如果沒問題再對專案進行單元測試(Unit Testing)或手動測試(Manual Testing)
  3. 如果都沒問題再 commit 目前合併無誤的版本到版本庫!

最後我們的 my-calc-branch 分支已經將新功能開發完成且測試無誤,所以要將 分支線路 ( /calc/branches/my-calc-branch ) 的最終版本合併回 開發主線 ( /calc/trunk ),這時的手續如下:

分支線路 ( /calc/branches/my-calc-branch ) 合併回 開發主線 ( /calc/trunk ) 通常選第 2 個,而特別選擇 [Reintegrate a branch] 這個選項是很重要的,因為這有以下好處:

  1. 讓 Subversion 能知道 開發主線 ( /calc/trunk ) 是從哪個分支、哪些版本合併進來的
  2. 有效節省 Subversion Repository (SVN儲存庫) 的空間,因為不用重複儲存分支的所有變更資訊
  3. 可以產生 Revision graph 得知專案開發的分支狀況

一樣可以先 測試合併(Test merge) 再正式進行 合併(Merge)

合併完後再將變更 commit 到版本庫

 

 

分支線路 ( /calc/branches/my-calc-branch ) 合併回 開發主線 ( /calc/trunk ) 並 commit 了之後,該分支就沒用了,該分支如果未來不再更新或繼續開發,Subversion 也不會繼續追蹤這個分支的變更 (因為之前已經 Reintegrate 過了),建議將該分支刪除。

刪除後要記得 commit 才能將「刪除動作」寫入到 Subversion Repository (SVN儲存庫) 中

 

以上就是一個 Subversion 分支與合併的完整過程,但有許多很細部的觀念我很難在一篇文章裡講清楚,如有時間建議多閱讀 Subversion 線上文件,當你建立起更多更完整的觀念後,對 Subversion 甚至是其他版本管理工具應該都能夠更加得心應手!

相關連結