Theme / v1.2.3

Matt Pocock's Engineering Skills

可組合的 AI 工程工作流技能庫

指令詳解

/resolving-merge-conflicts 指令詳解

逐 hunk 處理進行中的 git merge / rebase 衝突——依追溯至每一邊主來源的意圖來解決,然後完成操作,絕不 --abort

指令用途

/resolving-merge-conflicts 是一個用來解決進行中的 git merge / rebase 衝突的迴圈。獨立運作,不依賴其他 skills。

它的鐵律:絕不 --abort--abort 是投降 —— 它把整個操作倒退,丟掉已解決的工。這個 skill 的存在就是要不投降地把衝突解掉。

核心方法:逐 hunk(hunk by hunk),每個衝突塊都追溯每一邊的主來源,依意圖而非文字來解決。


運作流程

  1. 確認操作類型:是 merge 還是 rebase?衝突 hunk 有哪些?
  2. 逐 hunk 處理:一次一個衝突塊,不批次帶過。
  3. 追溯主來源:對每個 hunk,查ours 那邊是哪個 commit/branch 帶來的、想達成什麼;查theirs 那邊同樣。
  4. 依意圖解決:不是機械式挑一邊或文字拼接,而是理解兩邊各自想表達什麼,然後合成一個同時滿足兩邊意圖的結果。
  5. 繼續操作git add 已解決的、git rebase --continue 或完成 merge。
  6. 遇到新衝突:回到步驟 2,直到操作完成。

實戰對話範例

範例一:rebase 衝突

  • You:

    git rebase main 之後卡在衝突。

  • AI:

    先看衝突狀態:

    git status

    有 3 個檔案衝突。我逐檔逐 hunk 處理,絕不 –abort

  • AI(第一個 hunk):

    src/auth.ts 的 hunk 1:

    • ours(你的 branch):把 login() 改回傳 User 而非 void
    • theirs(main):給 login() 加了 rate-limit 參數。

    追溯意圖

    • ours 想要:呼叫端能拿到 user 物件。
    • theirs 想要:防止暴力登入。

    兩個意圖不打架 —— 合成:login(credentials, { rateLimit }) 回傳 User。兩邊都要。


範例二:merge 衝突裡的同文字不同意圖

  • You:

    兩個 branch 都把同一行改成 return null,結果 git 還是標衝突?

  • AI:

    這叫語義相同的文字衝突 —— 文字一樣但 git 仍標,通常是各自的上下文不同。我看一下:

    • ours 的上下文:在「找不到使用者」時 return null(語義:使用者不存在)。
    • theirs 的上下文:在「token 過期」時 return null(語義:需要重新登入)。

    文字相同但意圖不同 —— 這正是不能機械式挑邊的原因。正解:兩個 case 都要,分辨回傳:

    if (!user) return null;        // ours 意圖
    if (tokenExpired) return null; // theirs 意圖

為什麼「依意圖」而非「依文字」

機械解法的兩個失敗模式:

  1. 挑一邊、丟一邊--ours--theirs 全倒 —— 丟掉的那邊的意圖就沒了,後面會以 bug 形式回來。
  2. 文字拼接:把兩邊的程式碼硬拼起來 —— 文字都在,但語意破碎,編譯可能過、行為錯了。

依意圖解決:查每邊為什麼這樣改,合成保留兩邊意圖的結果。這比挑邊或拼接慢,但一次解對


主來源追溯

關鍵步驟是追溯每一邊的主來源

  • ours 這行是哪個 commit 帶來的?git log -L <line>,<line>:<file>git blame
  • 那個 commit 的 message 寫了什麼意圖?
  • theirs 同樣追溯。

沒有這一步,你只是在猜測兩邊想要什麼。


何時應該使用

  • git merge 卡衝突:任何 merge 衝突。
  • git rebase 卡衝突:任何 rebase 衝突。
  • cherry-pick 衝突:同類型。
  • 不確定該怎麼解某個 hunk:用它逐 hunk 走。

何時不應該使用

  • 沒有進行中的 merge/rebase:這個 skill 是為進行中的操作設計的。
  • 真的想放棄這次操作:如果你刻意--abort(例如這次 rebase 是個錯誤決定),那是合理選擇 —— 但那是你的決定,不是這個 skill 的預設。

注意:絕不 --abort

這個 skill 的鐵律是絕不 --abort。它的存在意義就是不投降地解掉衝突。如果你--abort,你就丟掉了:

  • 已經解決的 hunks 的工。
  • 對兩邊意圖已建立的脈絡理解。
  • 重新做一次時要重新累積的 context。

只有在你刻意判斷這次操作本身是錯的時才放棄,而且那是你的主動選擇,不是 skill 的路徑。


與其他技能的關係

/resolving-merge-conflicts 是一個獨立、隨時可用的 skill,沒有相依於其他 skills。它與其他 skills 的交集點:合併 Feature branch 時,常在 /implement + /code-review 收尾後、合進 main 時用到。不確定該用哪個 skill 時,用 /ask-matt 來路由。