7. Conflict 衝突
在前面幾章,我們學會了開闢平行宇宙(分支)以及合併(Merge)。Git 通常很聰明,只要兩個人改的是不同的檔案、或是同個檔案的不同行,Git 都會默默地幫你自動合體(Fast-forward 或自動合併)。
但是,天有不測風雲。
當主線宇宙(main)有人改了 index.html 的第 3 行,而你的平行宇宙(feature)也改了 index.html 的第 3 行。當你快樂地輸入 git merge 時……
此時 Git 會不知道到底「誰改的才是對的」,於是它會雙手一攤,把檔案丟回給你,叫你自己處理好:
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
這就是傳說中的衝突。Git 選擇不擅自作主,而是把決定權交還給你。
gitGraph
commit id: "建立專案 (Line 3: 原始文字)"
branch feature/conflict-test
checkout main
commit id: "main 修改 Line 3 (主線文字)"
checkout feature/conflict-test
commit id: "feature 修改 Line 3 (平行宇宙文字)"
checkout main
merge feature/conflict-test id: "💥 Conflict! 兩邊都改了 Line 3"1. 模擬衝突
為了學會解衝突,最好的方式就是自己搞出一場衝突。我們來實作一次:
步驟 1
在 main 分支改動第 3 行。確保你在 main 分支,把 index.html 的第 3 行改成:
<p>這是主線宇宙改寫的文字</p>
Code language: HTML, XML (xml)
然後打包提交:
git add .
git commit -m "style: update line 3 in main"
Code language: JavaScript (javascript)
步驟 2
去新分支改動「同一行」。我們從這個時間點開一個新分支,故意也去改第 3 行:
git checkout -b feature/conflict-test
打開 index.html,把第 3 行改成完全不同的東西:
<p>這是平行宇宙完全不一樣的文字!!!</p>
Code language: HTML, XML (xml)
一樣打包提交:
git add .
git commit -m "style: update line 3 in branch"
Code language: JavaScript (javascript)
步驟 3:
衝突!現在,切換回 main 分支,準備強行把新分支合進來:
git checkout main
git merge feature/conflict-test
此時終端機會跳出錯誤訊息,而且你的專案資料夾會進入 (main|MERGING) 的特殊狀態。
2. 所以怎辦 ?
這時候如果你用 VS Code打開 index.html,你會發現程式碼被 Git 塞了一些奇怪的符號:
<<<<<<< HEAD
<p>這是主線宇宙改寫的文字</p>
=======
<p>這是平行宇宙完全不一樣的文字!!!</p>
>>>>>>> feature/conflict-test
<<<<<<< HEAD:代表「你目前站的分支(也就是main)」裡面的內容。=======:楚河漢界。用來隔開雙方的修改。>>>>>>> feature/conflict-test:代表「你想合進來的那個分支」裡面的內容。
VS Code 會自動把這段衝突染成醒目的顏色(綠色與藍色),並在最上方提供四個點擊按鈕:
- Accept Current Change(採用目前變更): 留下
main(你目前的版本),丟掉分支的版本。 - Accept Incoming Change(採用來源變更): 留下分支(合進來的版本),丟掉你目前的版本。
- Accept Both Changes(同時保留雙方): 小孩子才做選擇,兩行我都留!
- Compare Changes(比較變更): 幫你左右對齊,細細比對。
實際解法工作流:
- 跟當事人討論(最重要): 去問問改那行程式碼的同事,確認到底要把誰的扣留下來。
- 點擊按鈕: 在 VS Code 上點擊你決定好的按鈕(例如點選 Accept Both Changes)。那些奇怪的
<<<、===符號就會瞬間消失。 - 存檔離開。
3. 重新提交
當你把檔案裡的所有衝突符號都清理乾淨、程式碼存檔後,Git 還在等你的最後一步:重新提交。
# 1. 告訴 Git 我把衝突檔案修好了
git add index.html
# 2. 重新 Commit(通常 Git 會自動幫你寫好 "Merge branch..." 的預設訊息)
git commit -m "fix: resolve merge conflict in index.html"
Code language: PHP (php)
輸入完後,你會發現終端機後方的 |MERGING 消失了,專案重回和平的狀態。恭喜你,完美拆彈!
小結
遇到 Conflict 真的不用怕,它代表 Git 正在盡忠職守地保護你的專案,防止你盲目覆蓋掉夥伴的成果。
- 衝突的原因:兩個人在不同的分支改了同個檔案的同一行。
- 解決的密碼:認清
HEAD(自己)與Incoming(他人),並用 VS Code 點選決定。 - 拆彈完畢後:務必重新
git add與git commit才能順利結束合併。
到這裡,你已經掌握了 Git 最核心、最精華、連許多實習生都會卡關的所有技術。你已經可以說自己「會用 Git 進行團隊協作」了!
