什麼是 Git 中的合併衝突?如何處理合併衝突?


在現實世界中,當我們合併分支時,經常會遇到衝突。衝突發生的原因如下:

  • 當同一行程式碼在兩個分支中以不同的方式更改時。

  • 在一個分支中更改了給定的檔案,但在另一個分支中刪除了該檔案。

  • 在兩個不同的分支中兩次添加了相同的檔案,但檔案的內容不同。

在這些情況下,git 將停止合併過程,因為它無法確定如何合併更改。在這種情況下,我們需要手動干預並指示如何繼續合併過程。

下圖顯示了兩個分支masterfeature。檔案hello.txt最初包含一行 Hello。初始提交後,由於它們具有單獨的提交,分支已分叉。每次提交都修改了檔案中同一行。

當我們嘗試將更改從 feature 分支合併到 master 分支時,我們會遇到合併衝突錯誤,如第二個圖所示。很明顯,git 將無法確定要保留哪個提交,因為第二行在每個提交中都不同。因此,它將提示我們確認是否只想保留 master 分支的更改,或只想保留 feature 分支的更改,或保留 feature 和 master 分支的更改。

示例

讓我們來看一下這個操作來理解合併衝突。

步驟 1 - 建立一個包含初始提交和hello.txt檔案的倉庫。

$ git init
Initialized empty Git repository in E:/tut_repo/.git/

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ echo hello>hello.txt

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git add .

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git commit -m 'hello.txt'
[master (root-commit) b6a745d] hello.txt
1 file changed, 1 insertion(+)
create mode 100644 hello.txt

步驟 2 - 建立一個新的分支 feature。切換到 feature 分支並透過編輯hello.txt檔案中的第二行來建立一個新的提交。

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git branch feature

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git switch feature
Switched to branch 'feature'

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (feature)
$ echo hello feature >> hello.txt

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (feature)
$ git add .

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (feature)
$ git commit -m 'hello feature'
[feature a004fa4] hello feature
1 file changed, 1 insertion(+)

步驟 3 - 現在切換到 master 分支並透過向 hello.txt 新增新行來執行新的提交。

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (feature)
$ git switch master
Switched to branch 'master'

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ cat hello.txt
hello

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ echo hello master>>hello.txt

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git add .

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git commit -m 'hello master'
[master 6478b3e] hello master
1 file changed, 1 insertion(+)

步驟 4 - 我們現在將嘗試將更改從 feature 分支合併到 master 分支。

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git merge feature
Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
Automatic merge failed; fix conflicts and then commit the result.

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master|MERGING)

輸出顯示該分支現在處於合併的中間狀態,因為由於衝突導致自動合併失敗。我們需要手動干預才能完成合並過程。

步驟 5 - 檢查檔案hello.txt的內容

$ cat hello.txt
hello
<<<<<<< HEAD
hello master
=======
hello feature
>>>>>>> feature

從檔案內容可以看出,第一行沒有改變。第二行將來自這兩個分支。輸出螢幕顯示一個用“=======”表示的分隔符。分隔符的第一半包含分隔符“<<<<<< HEAD”,這意味著內容來自當前分支(HEAD 指向 master)。分隔符的後一半包含分隔符“>>>>>> feature”,這意味著內容來自第二個分支 - feature。現在我們需要決定是保留前半部分還是後半部分,或者保留兩部分的更改。

步驟 6 - 我們決定保留兩部分的更改,因此我們手動修改檔案,只保留內容並刪除分隔符“=======”和分隔符“<<<<<< HEAD”和“>>>>>> feature”。

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master|MERGING)
$ cat hello.txt
hello
hello master
hello feature

步驟 7 - 現在提交更改並顯示歷史記錄。

$ git add .

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master|MERGING)
$ git commit -m 'merge commit'
[master 1183ce0] merge commit

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git log --oneline --all --graph
* 1183ce0 (HEAD -> master) merge commit
|\
| * a004fa4 (feature) hello feature
* | 6478b3e hello master
|/
* b6a745d hello.txt

更新於:2021年4月30日

816 次瀏覽

啟動您的 職業生涯

完成課程獲得認證

開始學習
廣告