SourceTree版本控管(九) - Unity Merge Conflict

在這幾個章節中我們的操作範例都是以新增檔案的方式來建立commit。通常在一個Unity開發中,即使我們將各個功能需求都獨立到不同的branch去開發,還是避免不了修改到同一個scene或者prefab的狀況,而每個檔案的meta檔也會隨著每次的編輯而改變,在這樣的狀況下去執行merge或rebase就會出現conflict(衝突),下面將模擬一個開發情境來比較清楚的了解conflict是如何產生。





首先我們建立一個Unity Project,專案裡面只有兩個folder,分別為Scenes與Scripts。
兩個folder分別存放MainScene.unity和MainManager.cs。
MainScene只存在一個叫做MainManager的空物件,且掛載著MainManager這個component。



接著建立一個新的branch叫做other,然後在Scprits folder新增Rotate.cs,
並且在MainScene創造一個Cube和Camera,
然後將Cube指派到MainManager Compnent的Target欄位上。



接著將Rotate.cs掛載到Cube上,並且把當前的編輯狀態commit到other branch上。



接著再回到master branch,在場景新增一個空物件Level,並且在底下建立一個Plane與Directional light,因為目前的commit處在master branch上,所以MainManager並沒有被更改到Target的欄位。



上述只是模擬出一個情境,稍微大概看過就好。

要注意的重點是目前兩個branch在分歧之後都各自commit新的版本,而且都編輯到了同一個場景。

接著開始merge這兩個 branch。




Merge完成之後,我們會看到MainScene.unity前面出現了一個驚嘆號的圖示,這表示MainScene.unity在merge的時候出現了conflict,而右邊的綠色區塊代表這次merge的變動範圍。



接著回到Unity Editor,我們發現Hierarchy Panel完全沒有任何的GameObject,在Console也出現了下面的提示。

The file Assets/Scenes/MainScene.unity seems to have merge conflicts, Please open it in a text editor and fix the merge.



使用任意一個文字編輯器來開啟MainScene.unity看看。



在這裡順便補充一下merge的說明,當我們merge兩個branch時,SourceTree偵測到這兩個branch都有編輯到同一個檔案(MinaManager.unity),這時候程式無法判斷我們想要究竟想要哪一邊的特性,於是就出現了conflict。

在Unity開發中,較常見的狀況是當一個scene、prefab或是script被多個branch編輯到的時候,在merge時就會出現conflict。

這時候SourceTree會在出現conflict的檔案做一些特別的註記,目的是讓開發者知道哪些改變是承接是哪一個commit。


因為這些註記是直接寫在MainScene.unity上,而Unity Editor根本無法辨別這些註記的格式,這會使得該場景無法正常作用,於是出現了剛才Hierarchy Panel完全沒有GameObject的狀態。

這時候我們可以使用Unity5的新特性 — Smart Merge來解決。
我們可以先看一下Unity Manual的說明文件。
Unity Smart Merge


首先我們點選工具選單Tools>Options。



在Diff標籤頁中找到Merge Tool的欄位,並且設定為Custom。



接著在下面的Diff Command 與 Argurment分別輸入下面的參數。

C:\Program Files\Unity\Editor\Data\Tools\UnityYAMLMerge.exe
merge -p $BASE $REMOTE $LOCAL $MERGED

設定完成後對著出現conflict的檔案點選 Launch External Merge Tool。



執行完畢之後我們會看到該檔案的驚嘆號圖示已經消失,右邊的預覽欄位也看不到先前那些註記了。



回到Unity Editor,我們發現merge之後兩邊branch新增的編輯內容都確實的結合在一起。



確認功能運作都正常之後,我們可以將*.orig 和其相關的*.meta檔刪除。
選取這兩個檔案後點擊右鍵 > Remove



或者是選取檔案後點擊上方工具列的Remove。



整理完當前的狀態後別忘了commit一個新版本。



總結:

當不同的branch都編輯到同一個scene / prefab 或是 script時,在merge都會產生conflict。

Scenes 與 prefabs 的merge conflict我們可以透過Smart Merge來解決。

如果是script的merge conflict,我們只能透過人工去處理。

不過還是有一些工具可以讓我們去做code的比對來加快處理程式碼在merge conflict的狀態。

例如 Beyond Compare




我們為一個專案做程式規劃時可以試著將功能需求獨立到不同腳本去開發。

除了可以減少scripts在merge時出現conflict的狀況,搭配Design Pattern可以讓程式碼更好維護或開發。

這些都是非常有效率的做法。



留言

張貼留言

熱門文章