很多人以為只有改到跟衝突相關的程式的人才有辦法去解這個衝突,很明顯這是錯誤的觀念。
++<<<<<<< .merge_file_a15412
+# 負責任的聲明
++=======
+ # 不負責任說明
++>>>>>>> .merge_file_a14308
這個要怎麼解呢?其實答案是"負責任的說明"你猜對了嗎?
假設你對了,那肯定是"猜"的,因為你根本沒有根據去推斷這個結果。
理由是我可以用不同版本創造出跟上述一模一樣的衝突,但因為是不同版本,所以答案一定不一樣。
所以說單純看上面衝突的樣子是不可能解出來的,因為你只看見上面跟下面各自最終的樣子,根本不知道過程。
這就是為什麼大部分人會依賴於"當事者"去處理衝突。
但事實上只要啟用 git 的 diff3 功能就可以處理這個問題。
git config --global merge.conflictstyle diff3
如果你先設定好 diff3,之後再去產生衝突,應該會長這樣。
<<<<<<< .merge_file_a04408
# 負責任的聲明
||||||| .merge_file_a13552
# 不負責任聲明
=======
# 不負責任說明
>>>>>>> .merge_file_a07884
你會發現中間多了一個區塊,這個區塊代表著上面跟下面版本之間某一時間點共通的樣子。
簡單講就是還沒改過的版本就是中間,上面是改完的某一版,下面是改完的另一版。
所以只要上面跟下面各自比對一下中間就可以知道各自到底想要幹嘛。
<<<<<<< .merge_file_a04408
# 負責任的聲明
||||||| .merge_file_a13552
# 不負責任聲明
=======
可以看見:
- 刪除了"不"
- 增加了"的"
||||||| .merge_file_a13552
# 不負責任聲明
=======
# 不負責任說明
>>>>>>> .merge_file_a07884
可以看見:
- 修改了
聲->說
所以正確地解開衝突的方式必須是讓結果含有上面與下面的更動。
也就是必須包含:
- 刪除了"不"
- 增加了"的"
- 修改了
聲->說
所以正解是:"負責任的說明"
一旦你打開 diff3 的功能,任何非當事人都可以判斷單一邊實際改動的部分。
然後再想辦法把兩邊的改動融合,就可以正確的處理衝突。
但儘管有人懂了這個邏輯還是會解錯,是因為判斷"實際改動"的部分有誤,所以融合時就做錯了。
還有縮排、換行、換順序等都會造成解衝突的困難,所以當時如果有拆出這些 commit 其實也是有幫助的。
之後有案例會再貼出來分享。