多個 AI Agent 共用同一個工作目錄時,很容易互相看見未完成的修改,切換 branch 也可能被 dirty working tree 擋住。git worktree 能讓每個任務使用獨立目錄與 branch,同時共用 Git 歷史,完成後再集中合併。

Worktree 隔離的是工作狀態,不是安全權限;真正的存取限制仍要靠 sandbox 或 container。若還不熟 branch、commit 與 merge,可以先參考 圖解 AI 時代的 Git 入門教學

Git worktree 是什麼

一般 git clone 會建立一份新的 repository 與工作目錄。git worktree add 則在原 repository 旁邊建立 linked worktree,連回同一份 Git 資料。原本 clone 出來的資料夾稱為 main worktree,後來增加的稱為 linked worktree。

每個 worktree 都有自己的工作檔案、HEAD、index、未提交修改與目前檢出的 branch。Git objects、refs、remotes、stash 與多數 repository config 則共用。因此,在 Agent A 建立 commit 後,Agent B 所在的 worktree 馬上能找到那筆 commit,不用先 push 到 GitHub。

main、agent login 與 agent tests 三個 Git worktree 各自保存工作檔案、HEAD 與 Index,共用 commits、branches、refs 與 remotes
各 worktree 隔離工作狀態,同時共用版本歷史。

Worktree 和 clone 的差別

項目git worktreegit clone一般切換 branch
工作目錄每個 worktree 一份每個 clone 一份只有一份
Git objects共用各自保存共用
同時開多個 branch可以可以不行
未提交改動彼此隔離彼此隔離切換時可能擋住
本地 branch/refs共用不共用共用
適合情境同一專案並行任務完全獨立的 repository一次只做一個任務

Worktree 節省的是 Git 歷史與切換成本,不是所有磁碟空間。每個工作目錄仍有完整檔案,node_modules、Python virtual environment、Gradle build、Docker volume 與編譯產物也可能各占一份。



Sponsored Links

Worktree 的建立方式

以下範例假設目前 repository 是 project,主要分支是 main,準備讓 Agent 處理登入功能。先在 main worktree 更新遠端資訊,再從 origin/main 建立新 branch 與工作目錄:

# 確認主工作目錄沒有未提交改動
git status --short

# 更新遠端 branch 資訊,不直接改動工作檔案
git fetch origin

# 從 origin/main 建立 agent/login,並檢出到旁邊的新目錄
git worktree add -b agent/login ../project-agent-login origin/main

# 查看所有 worktree、commit 與 branch
git worktree list

-b agent/login 會建立新 branch;../project-agent-login 是新工作目錄;最後的 origin/main 是起點。把三個參數寫完整,可以避免目前 main 落後遠端時,Agent 從舊 commit 開始工作。

如果 branch 已經存在,不加 -b

# 將既有 branch 檢出到新 worktree
git worktree add ../project-agent-login agent/login

# 建立暫時實驗目錄,不綁定 branch
git worktree add --detach ../project-experiment origin/main

Detached HEAD 適合一次性測試、重現 bug 或跑 benchmark。需要保留改動時,必須在移除前建立 branch 或 tag,讓 commit 持續可達;只記下 hash 仍可能在日後被 Git garbage collection 清除。

同一個 branch 不能同時檢出

Git 預設不允許兩個 worktree 同時檢出同一個 branch。因為 branch pointer 是共用的,其中一邊 commit 會移動 branch,另一邊的工作檔案卻沒有跟著更新,容易造成狀態不一致。

--force 可以繞過部分保護,但多 Agent 流程不該靠它。建議採用一個任務一個 branch,例如 agent/loginagent/paymentagent/tests,branch 名稱也能直接對應 Agent 的責任範圍。

多個 AI Agent 並行開發流程

Worktree 只隔離工作目錄,不會自動拆解任務。適合並行的工作應該有清楚邊界,例如前端登入畫面、後端驗證 API、測試補強。若三個 Agent 都要大改同一個核心檔案,執行時不互相覆蓋,合併時仍會產生 conflict。

三個任務目錄的配置

# 所有任務從同一個 origin/main 起點開始
git fetch origin

git worktree add -b agent/login-ui \
  ../project-agent-login-ui origin/main

git worktree add -b agent/auth-api \
  ../project-agent-auth-api origin/main

git worktree add -b agent/auth-tests \
  ../project-agent-auth-tests origin/main

git worktree list

接著開三個終端機,分別進入對應目錄啟動 Agent。Claude Code、Codex、Cursor、Copilot CLI 或其他 coding agent 都遵循相同原則:Agent 啟動時所在的目錄,就是它主要能看到與修改的工作空間。

# 終端機一:前端登入畫面
cd ../project-agent-login-ui

# 終端機二:驗證 API
cd ../project-agent-auth-api

# 終端機三:測試
cd ../project-agent-auth-tests

每個 Agent 的完成條件

交付條件不能只寫「功能完成」。每個 Agent 至少要回報變更範圍、執行過的測試、未解決問題與 commit hash。建議在專案的 Agent 指引中加入以下規則:

  • 只能處理指定任務,不順手重構無關檔案。
  • 開始前確認 git status 與目前 branch。
  • 完成後執行該任務需要的 lint、type check 與測試。
  • 使用 git diff --stat 檢查是否改到責任範圍外。
  • 建立小而完整的 commit,不把多個目的塞進同一筆。
  • 回報 commit hash,不自行合併 main 或刪除 worktree。

開發者因此不必等 Agent A 完成才開始 Agent B。等待測試、下載依賴套件或分析大型 codebase 的時間可以重疊,最後仍保留三條能分開 review、退回與重跑的 commit 歷史。

Git worktree 多 Agent 開發從拆分任務、建立 worktree、並行工作、整合測試到 review 清理的五步驟流程
一個任務對應一個 branch 與工作目錄,最後集中整合。

整合與合併順序

三個 Agent 都完成後,不要讓它們同時往 main 合併。指定一個 integration worktree,由開發者控制合併順序、解 conflict 與跑完整測試,可以避免 main 在整合途中出現尚未完成整合的狀態。

# 建立整合用 branch 與 worktree
git fetch origin
git worktree add -b integrate/auth \
  ../project-integrate-auth origin/main

cd ../project-integrate-auth

# 依相依關係合併:API、UI、測試
git merge --no-ff agent/auth-api
git merge --no-ff agent/login-ui
git merge --no-ff agent/auth-tests

# 跑完整測試後再推送整合 branch
npm test
git push -u origin integrate/auth

--no-ff 不是必要條件,但會留下每個任務分支的 merge commit,之後比較容易看出哪一組改動來自哪個 Agent。團隊若習慣 linear history,也可以先 rebase 任務 branch,再 fast-forward 或 squash merge;重點是整合策略要一致。

Merge conflict 仍然存在

Worktree 解決的是工作檔案互相覆寫,不會消除不同 branch 之間的重疊或不相容修改。同一行、相鄰區塊、刪除與修改同一檔案,以及 rename/rename 都可能讓 Git 合併時停下來要求處理 conflict。任務切得越接近目錄或模組邊界,最後的整合成本越低。

遇到 conflict 時先理解兩個改動的目的,再決定保留、重寫或調整介面,不建議把整個 conflict 直接交給不知道完整需求的第三個 Agent。可以請 Agent 分析差異,但最後要重新跑整合測試。

兩個 Agent 在不同 worktree 執行時不會覆寫檔案,但修改相同程式碼後合併仍會產生 merge conflict
隔離工作目錄不等於消除 merge conflict。

環境變數、依賴與開發伺服器

Git 只會把 tracked files 檢出到新 worktree。通常被 .gitignore 排除的 .env、憑證、local database、IDE 設定與 dependency 不會自動出現。Agent 一進新目錄就執行測試,常見結果是缺少環境變數或套件。

每個 worktree 的環境準備

  • .env.example 建立各 worktree 的 .env,敏感值再由安全來源填入。
  • 開發伺服器使用不同 port,例如 3001、3002、3003。
  • 測試資料庫使用不同 database name 或 schema,避免同時清空資料。
  • Node、Python、Gradle 等 dependency 使用共用下載 cache,但各 worktree 保留自己的安裝與 build 目錄。
  • 不要讓多個 Agent 同時寫入同一個 generated file、SQLite database 或 coverage output。

直接 symlink 同一份 node_modules 有時能省空間,但 package manager 更新、native module 與 build cache 可能互相影響。比較穩定的方式是讓 pnpm store、npm cache、Gradle cache 共用下載內容,worktree 內的安裝結果仍各自保存。

Worktree 專用 Git config

Repository config 預設由所有 worktree 共用。若需要讓 sparse checkout 或其他 Git 設定只套用到某個 worktree,可以啟用 worktree config:

# 整個 repository 啟用 worktree-specific config
git config extensions.worktreeConfig true

# 只在目前 worktree 寫入設定
git config --worktree example.setting value

這個 extension 可能讓過舊的 Git 無法讀取 repository,團隊使用前要先確認版本。應用程式的 port、API key 與資料庫連線仍適合放在每個目錄自己的 .env,不要塞進 Git config。

Worktree 清理與修復

功能合併後,先確認 worktree 沒有未提交檔案,也要備份被 .gitignore 排除但仍需保留的 .env、local database 與產出檔,再用 Git 指令移除。直接從 Finder 或檔案管理員刪除資料夾,會留下 .git/worktrees 裡的管理資料。

# 查看所有 worktree 與狀態
git worktree list --verbose

# 移除已完成且乾淨的工作目錄
git worktree remove ../project-agent-login-ui

# 確定 branch 已合併後再刪除 branch
git branch -d agent/login-ui

# 預覽哪些失聯管理資料會被清理
git worktree prune --dry-run --verbose

# 執行清理
git worktree prune --verbose

git worktree remove 預設拒絕刪除有 tracked 修改或一般 untracked files 的 worktree,但 ignored files 可能隨目錄一起刪除。--force 會略過更多保護,執行前要自行確認工作檔案與 ignored files 都不再需要。

lock、move 與 repair

# 保護暫時離線的外接硬碟或網路磁碟 worktree
git worktree lock --reason "external SSD" ../project-agent-login-ui

# 解除保護
git worktree unlock ../project-agent-login-ui

# 使用 Git 搬移 worktree
git worktree move ../project-agent-login-ui ../work/login-ui

# 手動搬動後重新建立管理資料連結
git worktree repair ../work/login-ui

lock 適合不一定掛載的外接裝置與網路共享磁碟(network share),避免 Git 把暫時找不到的 worktree 判定成可清理。一般本機資料夾使用 move 搬遷;已經手動搬動 main worktree 或 linked worktree,才使用 repair 修復路徑。

多 Agent 使用 worktree 的限制

  • Branch 與 refs 共用:一個 Agent 刪 branch、rebase 或 reset,其他 worktree 也會看到結果。
  • Stash 共用:不要用模糊的 stash 名稱交接多個 Agent,優先讓每個任務 commit 到自己的 branch。
  • 磁碟使用量仍會增加:大型 dependency、build output 與資料集會在每個目錄出現。
  • 服務資源可能衝突:port、database、container name 與暫存檔需要分開。
  • 相同程式碼仍會 conflict:平行時間縮短,不代表整合成本消失。
  • Submodule 支援不完整:Git 官方仍不建議對含 submodule 的 superproject 建立多份 checkout。

因此,worktree 適合把可分割的任務平行化,不適合為了同時開更多 Agent 而強行拆分高度相依的工作。兩個 Agent 如果必須輪流修改同一套 schema 與 migration,依序完成通常比最後處理大量 conflict 快。

常見問答

Git worktree 會複製整個 repository 嗎?

不會複製 Git object database 與完整歷史,但會建立一份工作檔案。未追蹤的 dependency、build output 與環境檔案要另外準備,也會占用各自的磁碟空間。

可以讓兩個 Agent 使用同一個 branch 嗎?

Git 預設禁止同一個 branch 同時檢出到兩個 worktree。多 Agent 應各用一個 branch,完成後再 merge 或 cherry-pick,不能把 --force 當成一般做法。

Worktree 和 branch 哪個比較適合 AI Agent?

兩者不是二選一。Branch 隔離 commit 歷史,worktree 讓不同 branch 同時出現在不同工作目錄。單一 Agent 使用 branch 已足夠;多個 Agent 同時工作時,再為每個 branch 建立 worktree。

Worktree 裡的 commit 需要 push 才能被其他 worktree 看見嗎?

不需要。所有 linked worktree 共用同一份本地 Git objects 與 refs,commit 建立後便能從其他 worktree merge、rebase 或 cherry-pick。需要跨電腦或備份到遠端時才 push。

刪除 worktree 會一起刪除 branch 嗎?

不會。git worktree remove 移除工作目錄與 worktree 管理資料,branch 仍然保留。確認已合併後,再使用 git branch -d branch-name 刪除 branch。

參考來源


Sponsored Links

發佈留言