Git Worktree 的故障模式是可預測的
Git worktree 讓每個 AI agent 擁有自己的工作目錄、自己的 branch、自己的 staging area。這解決了兩個 agent 同時編輯同一個檔案的問題。但 worktree 之間共享的東西比你想的多:.git 物件資料庫、lock 檔機制、以及 agent 平行修改的所有被追蹤檔案。這些共享層面產生六種不同的衝突類型,每種都有明確的成因、診斷方式和修復方法。
如果你是第一次設定 worktree,請先看 Git Worktree 多 Agent 設定指南。這篇文章假設你的 worktree 已經在跑,而且出了問題。
1. Lock 檔衝突
現象: 兩個 agent 在不同 worktree 中各自執行 npm install(或 yarn install、pnpm install)。每次安裝都修改 lockfile(package-lock.json、yarn.lock 或 pnpm-lock.yaml)。因為 lockfile 被 git 追蹤,兩個 agent 在各自的 branch 上產出不同版本的 lockfile。合併時出現 5,000 行的 diff,沒有人能手動 review。
原因: Lockfile 對每次安裝是確定性的,但跨 branch 不是。如果 agent A 裝了 zod,agent B 裝了 date-fns,兩邊都會重新產生整棵依賴樹的 lockfile。即使實際的依賴變更很小,結果檔案幾乎每行都不同。
診斷:
# 檢查 worktree 中 lockfile 是否被修改
cd ~/project-feature-auth
git diff --name-only main -- package-lock.json yarn.lock pnpm-lock.yaml
修復:
# 方法 1:從合併後的 package.json 重新產生 lockfile
git checkout main
git merge feature-auth --no-commit
# 接受兩邊的 package.json 變更
# 然後重新產生 lockfile
npm install # 或 yarn install / pnpm install
git add package-lock.json
git commit -m "merge feature-auth with regenerated lockfile"
# 方法 2:用 npm 內建的 merge driver
npx npm-merge-driver install -g
# 之後的合併會自動處理 package-lock.json 衝突
預防: 在 .gitattributes 中加入規則,讓 git 用 npm merge driver 處理 lockfile。或者協調 agent 的工作,讓只有一個 branch 安裝新依賴,其他 agent 用現有的依賴集合。
package-lock.json merge=npm-merge-driver
2. Git Index Lock 錯誤
現象: Agent 的 git 操作失敗,錯誤訊息如下:
fatal: Unable to create '/path/to/repo/.git/worktrees/feature-auth/index.lock': File exists.
Agent 無法 stage 檔案、commit、或執行任何對 index 的寫入操作。
原因: Git 在任何寫入操作前會建立 index.lock 檔,防止同時修改。如果 agent process 當掉、終端被關閉、或系統在 git 操作進行中斷電,lock 檔就會殘留。每個 worktree 有自己的 index lock,位在 .git/worktrees/<name>/index.lock,所以只影響當掉的那個 worktree。
診斷:
# 檢查所有 worktree 是否有殘留的 lock 檔
find .git/worktrees -name "index.lock" -ls
# 確認是否有 git process 還在執行
ps aux | grep git
修復:
# 確認沒有 git process 在使用這個 lock 後才刪除
rm .git/worktrees/feature-auth/index.lock
預防: 不要用 kill -9 終止 agent process,也不要在 git 操作進行中關閉終端。用 kill -15(SIGTERM),讓 process 有時間清理。如果你用 Claude Code 的 --worktree 跑 agent,讓 session 用 /exit 正常結束,不要強制關閉終端。
3. Branch Checkout 衝突
現象: 你嘗試為一個已經被 checkout 的 branch 建立 worktree:
fatal: 'feature-auth' is already checked out at '/Users/you/project-feature-auth'
原因: Git 強制一個 branch 只能被一個 worktree checkout。這是刻意設計的。如果兩個 worktree checkout 同一個 branch,一邊的 commit 會無聲地移動另一邊的 HEAD,造成損壞狀態。這個錯誤是保護機制。
診斷:
# 看哪些 branch 在哪些 worktree 被 checkout
git worktree list
/Users/you/project abc1234 [main]
/Users/you/project-feature-auth def5678 [feature-auth]
修復:
# 方法 1:從現有 branch 建立新 branch
git worktree add ../project-auth-v2 -b feature-auth-v2 feature-auth
# 方法 2:先移除不需要的舊 worktree
git worktree remove project-feature-auth
git worktree add ../project-feature-auth-new feature-auth
預防: 用命名慣例把 worktree 名稱綁定到 agent session。例如 feature-auth-agent1 和 feature-auth-agent2。Claude Code 的 --worktree flag 會自動產生不重複的 worktree 名稱。
4. 合併時的程式碼衝突
現象: Agent A 在 feature-auth branch 修改了 src/routes/index.ts。Agent B 在 feature-api branch 也修改了同一個檔案。合併兩個 branch 到 main 時,git 無法自動解決重疊的變更。
原因: Worktree 在檔案系統層級隔離 agent,但不在語義層級協調。兩個 agent 開發不同功能時,經常會碰到共用的檔案:路由定義、設定檔、barrel export、type 定義、資料庫 schema。這些「熱點檔案」是每個 feature branch 都傾向修改的檔案。
診斷:
# 合併前先檢查重疊檔案
git diff main...feature-auth --name-only > /tmp/auth-files.txt
git diff main...feature-api --name-only > /tmp/api-files.txt
comm -12 <(sort /tmp/auth-files.txt) <(sort /tmp/api-files.txt)
這會列出兩個 branch 都修改的檔案。清單越長,衝突越痛。
修復:
# 先合併第一個 branch
git checkout main
git merge feature-auth
# 合併第二個 branch(衝突會在這裡出現)
git merge feature-api
# 手動解決衝突,然後:
git add .
git commit -m "merge feature-api, resolve conflicts with feature-auth"
如果合併過程中遇到 lockfile 衝突,參考上面的 lockfile 章節。
預防: 這是最難預防的衝突,因為需要合併前的規劃。三種策略有效:
- 熱點檔案的單一寫入者規則。 指定一個 agent 負責共用檔案(例如路由定義)。其他 agent 把自己的路由寫在獨立檔案中,透過 import 整合。
- 頻繁合併。 不要讓 branch 分歧好幾天。第一個完成的 branch 先合併到 main,剩下的 branch 在完成前先 rebase。
- 只做新增的變更。 透過 CLAUDE.md 或 prompt 指示 agent 在獨立檔案中新增 export、route、type,而不是修改現有檔案。新增很少衝突。
關於如何協調多個 AI agent 跨 worktree 工作,2026 AI CLI 工具完整指南有更全面的說明。
5. 過期的 Worktree 參照
現象: git worktree list 顯示已經不存在於磁碟上的 worktree。Git 指令偶爾會警告有孤立的 worktree metadata。
原因: 如果 agent session 當掉,或你用 rm -rf 刪除 worktree 目錄而不是用 git worktree remove,git 會保留 worktree 的 metadata 在 .git/worktrees/ 中。Worktree 出現在 git worktree list 但目錄已經不見了。這會阻止你用相同名稱或 branch 建立新的 worktree。
診斷:
# 列出所有 worktree,檢查是否有可清理的項目
git worktree list --porcelain
# 預覽哪些會被清理
git worktree prune --dry-run
修復:
# 移除所有過期的 worktree 參照
git worktree prune
# 確認清理結果
git worktree list
如果被清理的 worktree 的 branch 還有未合併的工作,branch 本身不受影響。清理只移除 metadata 連結,commit 留在 repository 中。
預防: 一律用 git worktree remove <path>,不要用 rm -rf。如果你用腳本自動化 worktree 的生命週期,把 git worktree prune 加入清理步驟。一個簡單的 alias 很有用:
# 加到 .bashrc 或 .zshrc
alias gwtclean='git worktree prune --dry-run && git worktree prune && git worktree list'
6. Build 產物汙染
現象: 某個 worktree 的 build 指令產出損壞或過時的結果,因為它讀到其他 worktree 產生的 cache。症狀包括建置失敗、bundle 內容錯誤、或測試在一個 worktree 通過但在另一個失敗。
原因: Next.js(.next/)、Vite(dist/)、TypeScript(tsconfig.tsbuildinfo)等 build 工具寫入相對於專案根目錄的位置。如果 worktree 之間共享 build cache(cache 目錄設為絕對路徑,或 monorepo 工具把 cache 存在共用位置),agent 之間的 build 就會互相汙染。
另外,node_modules/ 通常不在 worktree 之間共享(各有一份),但如果某個 worktree 的 node_modules 是從主 worktree symlink 過來的,當一邊的 agent 修改 package.json 時,依賴解析就會出問題。
診斷:
# 檢查是否有共用的 cache 目錄
ls -la .next/ dist/ .turbo/ node_modules/.cache/
# 比較跨 worktree 的 build fingerprint
md5sum ../project-feature-auth/.next/BUILD_ID .next/BUILD_ID
修復:
# 清除受影響 worktree 的 build cache
rm -rf .next/ dist/ .turbo/ node_modules/.cache/ tsconfig.tsbuildinfo
npm run build
預防: 確保 build 工具使用 worktree 內的本地 cache 目錄。Next.js 預設就是這樣(.next/ 相對於專案根目錄)。支援自訂 cache 路徑的工具,指向 worktree 內部的目錄:
// turbo.json 的 cache 預設就是 worktree 本地
// 多數工具不需要改
// 自訂 build 腳本用相對路徑
// 錯誤:CACHE_DIR=/tmp/shared-build-cache
// 正確:CACHE_DIR=./.build-cache
把 build 輸出目錄加進 .gitignore(如果還沒加的話)。每個 worktree 應該從原始碼獨立 build。
監控多個 Worktree
當你有三個以上的 worktree 在運作,重心從修復衝突轉移到提早偵測衝突。你需要看到每個 agent 在哪個 branch、是否有未 commit 的變更、哪些 branch 跟 main 分歧了。
# 快速檢查所有 worktree 的狀態
git worktree list | while read dir rest; do
echo "=== $dir ==="
git -C "$dir" status --short
done
手動執行這些指令很快就會膩。如果你同時管理多個 agent 終端,Termdock 在單一畫面中顯示所有 worktree 的 git 狀態,每個終端 pane 都會顯示它的 branch 和變更數量,你可以拖拉調整需要關注的 agent 視窗大小。
速查表:衝突類型對照
| 衝突類型 | 症狀 | 一行修復 |
|---|---|---|
| Lockfile 分歧 | 合併時出現數千行 lockfile diff | 合併 package.json 後執行 npm install |
| Index lock 錯誤 | Unable to create index.lock | rm .git/worktrees/<name>/index.lock |
| Branch 已被 checkout | fatal: already checked out | git worktree add -b new-branch-name |
| 合併衝突(共用檔案) | CONFLICT (content) | 先合併第一個 branch,rebase 第二個,手動解決 |
| 過期 worktree | worktree list 出現不存在的項目 | git worktree prune |
| Build cache 汙染 | build 輸出錯誤、測試失敗 | rm -rf .next/ dist/ 後重新 build |
六種衝突的根本原因都是共享狀態。Worktree 隔離了工作目錄,但共享 git 資料庫、跨 branch 的追蹤檔案、以及用絕對路徑設定的 cache。辨識是哪一層的共享造成你的衝突,是最快找到修復方法的路徑。
完整的平行 AI agent worktree 設定指南,請看 Git Worktree 多 Agent 設定。更廣泛的 AI CLI 工具在現代開發流程中的定位,2026 AI CLI 工具完整指南有全面的整理。
Ready to streamline your terminal workflow?
Multi-terminal drag-and-drop layout, workspace Git sync, built-in AI integration, AST code analysis — all in one app.