git 遇上二進位檔的 conflict 解法

先前用 git 只處理過 text-base 的程式碼,最近要合併(merge)一組二進位檔(binary file)才發現從來沒遇過的情況。

一般來說,git merge 遇到衝突(conflict)的情況,如果是 text-base 的程式碼,會在檔案中插入文字標記讓使用者選擇需要的片段。例如:

<<<<<<< HEAD
contact : email.support@github.com
======= 
please contact us at support@github.com
>>>>>>> iss53

在 <<<<<<< 與 ======= 之間的是當下目錄中的版本的片段,======= 與 >>>>>>> 間的則是待合併的版本的片段。由於兩個要合併的版本間有這些程式碼的差異,需要使用者做選擇。要把這些提示文字處理掉才算是解決衝突,以便繼續進行合併。

不過二進位檔案不同版本間無法比較。在衝突操作上,只能就整個二進位檔案進行版本的選擇,而無法針對程式碼片段來處理。

以下以 TortoiseGit 這套 git GUI 做為範例來說明。在 bash 環境下原理也一樣。

在 TortoiseGIt 下遇到衝突會出現下圖這樣子的訊息,說明無法合併二進位檔。

git-merge-conflict1

若在右鍵選單中選取 Resolve…(下圖),會跳出需要去解決的衝突檔案列表。

git-merge-conflict4

再待處理的衝突檔案上按右鍵,會跑出下圖的選單。

git-merge-conflict5.png

「Resolve conflict using ‘mine’」就是選用當下目錄的版本(HEAD)做為合併後的版本。如果使用者在 master 分支,要合併到 dev 分支,也就是:

$ git checkout master
$ git merge dev

「Resolve conflict using ‘mine’」便會使用 master 的版本來解決衝突。相對的,「Resolve conflict using ‘theirs’」便是選用 dev 的版本做為合併後的版本。

還有一個選項是「resolved」,實測後也是選用當下目錄的版本。理論上應該還是有區別,個人猜想是從 git rebase 的操作需要來的。待高手說明了。

至於選單最上面的「Edit conflicts」點開後,因為是二進位檔,無法做所謂「edit」的動作。但是目錄中會跳出三個額外的檔案(下圖),也就是 git merge 時做為合併依據的三方:共同祖先版本(BASE)、現有目錄中的版本(LOCAL)與待合併的分支的版本(REMOTE)。其中 LOCAL 就是前面提到的 mine,而 REMOTE 就是 theirs。使用者也可以在這邊檢視不同版本的細節,供做合併的參考。

git-merge-conflict3.PNG

當然上述三個檔案對於程式開發是額外的,衝突處理完便可以刪掉了。

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s