2009年7月4日 星期六

[程式設計] 把修正好的程式碼合併到目前工作副本 – svn merge

老實說, 我不太敢作 svn merge!

因為 source code 實在太重要了, 特別是要合併兩個不同的 source tree.


當時的直覺反應是:
[若沒有仔細瞭解 merge 的機制, 絕對不要動它.] 我擔心會搞爛整個 source tree.

後來才知道, 原來只要不 commit, 怎麼亂搞都不會出事  ^_^

 

緣起

當有一天你要同時管理 3 個以上的專案時, 同步管理專案的問題就會出現. 例如:  A 專案修正後的程式碼, 想要同時讓 B 與 C 分享.


我們的問題可以分類成:
1. 少於 10 行而且集中在一起的程式碼: 直接手動把你要的部分, 複製到想要被更新的專案中, 這樣最快.

2. 當修正的程式碼, 散佈在多個檔案而且多個位置: 這時候與其他專案的同步修正, 就會是一個問題.

我遇到了 case 2! 而且我的組員還不斷地新增程式碼.


心理障礙

主要是 B 和 C 的程式碼已經有各自的功能了, 不能直接把 A 的 code 複製進去.
必須先把有修改的程式檔找出來, 找出需要修正的段落, 然後把適當的程式填進去.

這樣須要花費巨大的比對與校正心力, 為了解決專案同步的問題, 我還使用一個 Excel 檔記錄專案之間, 有哪些 bug 的修正還沒同步.

通常做完這些修正後, 我都會找 Larry 一起去買香雞排.


面對問題

其實我是標準程序的守護者, 我善於寫文件.

我寫文件的重點是:[創造一個不需要我的工作環境],


我希望任何人無論你是高手還是初學者, 只要拿到文件, 就能做的和我一樣. 而且有效率的完成工作.

根據這樣的理念, 所以最好的文件是不用文件, 一切都用批次作業自動完成.

我總是認為如果我花費太多時間在某件困難的事物上, 那就表示這件事有必要寫份文件或自動化, 讓我花的時間不用重複的浪費.


手冊越簡單越好

我希望連沒有 svn 觀念的人, 只要按照手冊描述的步驟就能完成.

通常我認為步驟若超過 7 個以上, 那就表示這份文件太複雜了, 有必要修改文件內容.
基本上,

我喜歡看到 4 個步驟就完成的工作項目. 第四個步驟的內容是 Enjoy!


請放心

merge 改的是你硬碟中的程式工作副本(working copy), 除非你 commit, 否則不會改到 repository.

如果你發現你的工作副本已經一團亂了, 直接下 revert 即可將整個 source code 恢復原狀


把修正好的程式碼合併到主線最簡單的步驟

其實只要閱讀一下 help, 我們就可以大概瞭解 merge 的功用了

Step 1: 進入 cmd.exe

Step 2: set LANG=en (if you don’t, 你可能會遇到一堆數字的亂碼)

Step 3: svn help merge

merge: Apply the differences between two sources to a working copy path.

意思就是把兩個 source 的差異部分合併到目前的工作副本中

所以若要將修改前與修改後的程式碼, 全部合併到目前的工作副本中, 那麼作法很簡單


Step 1: 點選要接受合併的 working copy

例如: 我們希望把 branch source tree 的解決 bug 片段, 也放到 trunk source tree 中. 作法只要在 trunk 目錄上點選滑鼠右鍵選Merge即可.

01_choose_working_copy

 

Step 2:  Merge Type 選 “Merge a range of revision”, 在裡面指定修改前與修改後的 branch source 版本號碼.

02_type1

  a. 選擇已經除錯完成的 branch source tree

03_Merge  

    b. 選擇在 branch source tree 中, 哪個 bug 片段要被取出來.

         例如: 我們只想取出 Bug2 修正後的片段, 進行合併

         作法如下: [Revision range to merge] ->[Show log]

choose_bug_fixed

Step 3: 點選 [Next], 然後 [Merge], 就會將你在 branch 修改過的程式碼, 合併到指定的 working copy.

merge_final 

Step 4: 完成, Enjoy.

 

合併的結果
狀況 1: 若你選擇的程式碼中, 修正的部分剛好你的 working copy 版本也改了. 這時候就會發生衝突. (這種情況很常發生, 所以你要會用小烏龜解衝突!)

conflict01

我們在這時候出手, 選擇哪一部份程式碼是你要的修正, 那一部份是不要的.

(小烏龜可以幫你快速找出要改的地方, 幾乎可以不用鍵盤的改衝突)

 

狀況 2: 在你選擇的程式碼中, 剛好修正的部分可以完全鑲入你的 working copy.

merge_ok

 

合併完成後的檢查

Step 1: 合併後, 在你的 working copy 中有檔案變動時, 檔案會變成紅色驚嘆號.

Step 2: 執行 diff (小烏龜滑鼠右鍵), 觀察程式碼片段中的每項更改是否為你想要的.

abc

Working copy 狀態: 左邊是原來的, 右邊是目前更新的內容

Step 3: 處理完後, 在小烏龜 diff 視窗左上角, 點選 save 完成手動合併工作. 接者取下一個驚嘆號檔

Step 4: commit 修改後的 working copy.

 

--------------------------------------------------------------------------------------

命令列的作法:

有一個主線, 為了修一個 bug 建立另一個分支.  現在 bug 已經修正完畢, 如何將修正後的 code 合併到主線的 working copy 呢?

作法如下:
Step 1: 先執行 cmd.exe, 並且切換到主線的 working copy 中.

Step 2: 查出發現 bug 之前的那段起始號碼

svn -log [分支的 svn source tree] (查詢開始修改 bug 前的版本號碼)

Step 3: 只合併修改 Bug 的部分到目前所在的 working copy 中

svn merge -r [修改 bug 前的號碼]:HEAD [分支的 svn source tree]

Step 4: 主線即擁有你修改的 bug.

 

Enjoy!

by Jing.