同一個 repo 同時開兩個 Codex Agent,很快就會遇到一個看似奇怪的情況:兩邊明明各有一條 branch,為什麼還是不能放心讓它們在同一個資料夾裡一起改?
因為 branch 沒有替你複製第二份工作目錄。
branch 記的是一條開發線目前指向哪個 commit;worktree 才會多出另一份實際可編輯的目錄,並保有自己的 HEAD、index 與未提交狀態。[1][2] 兩個 Agent 如果仍然待在同一個 working directory,它們碰到的還是同一批檔案與同一份 checkout 狀態。
Codex App 把 worktree 做進多 Agent 工作流,就是為了讓同一個 repo 上的平行任務可以各自在隔離的 code copy 裡施工,而不必共用同一份本機 Git working state。[4]

Figure 1|四個概念各自處理不同問題。這是一張操作心智模型,不是 Git 官方 taxonomy。
先把四個概念放回各自的位置
如果只記名詞,很容易把 branch、worktree 和 PR 都想成「另一條 Git 路線」。實際上,它們各自管的是不同層。
| 名詞 | 最適合回答的問題 | 主要責任 | 它不會替你完成什麼 |
|---|---|---|---|
| Git | 這個 repo 有哪些版本歷史? | commits、objects、refs 與版本資料 | 工作目錄隔離 |
| Branch | 這條開發線目前指到哪個 commit? | 一個會移動的 commit reference | 第二份專案目錄 |
| Worktree | 這個 task 現在在哪份檔案狀態裡施工? | 額外的 working directory,以及自己的 HEAD、index、未提交狀態 | VM、container 或完整執行環境隔離 |
| PR | 這組變更要怎麼被檢查並收進目標 branch? | hosting platform 上的討論、review、checks 與 merge 流程 | working copy 或 branch 本身 |
Pro Git 把 branch 定義成指向 commit 的 lightweight movable pointer。[1] 建立 branch 只多了一個 reference,不會複製一套專案檔案。
git worktree 做的事情不同。Git 允許同一個 repository 同時掛著多個 working trees;它們仍然共享 repository 的大部分資料,但各自保有 HEAD、index 等特定狀態。[2]
PR 又在另一層。以 GitHub 為例,PR 把 head branch 的變更放進一個可討論、可 review、可跑 checks、最後決定是否合進 base branch 的協作流程。[3]
所以一個多 Agent 任務可以同時用到 branch、worktree 和 PR,但這不代表三者可以互換。
Branch 分開開發線,Worktree 分開施工空間
假設現在有兩件互不相同的工作:
Task A: refactor payment retry logic
Task B: update checkout UI
你可以先準備兩條 branch:
agent/payment-retry
agent/checkout-ui
但如果兩個 Agent 都在這裡工作:
~/project/
它們仍然共用同一個 working tree。
Agent A 正在修改檔案時,Agent B 如果 checkout 另一條 branch、restore 檔案、reset 或改動 index,操作的都是同一份目錄狀態。Git 也可能因為未提交變更而拒絕切 branch,逼你先 commit、stash 或處理 dirty state。
人類單線開發通常感覺不到這個問題,因為同一時間往往只有一個人在操作那個資料夾。兩個 Agent 可以真的同時讀檔、改檔和跑指令,共用 working tree 就變成 concurrency 問題。
換成 worktree,檔案層可以拆成:
~/project/ -> main worktree
~/project-payment/ -> agent/payment-retry
~/project-checkout/ -> agent/checkout-ui
自己用 Git CLI 建立其中一份時,可以寫:
git worktree add ../project-payment -b agent/payment-retry main
這會建立新的 linked worktree,並從 main 建立 agent/payment-retry 給它使用。[2]
到這一步,你能確認的是:Task A 有了另一份可獨立 checkout、修改與保留未提交狀態的 working directory。
這條指令沒有順便保證其他事情。它不會證明兩個 task 最後一定能無衝突合併,也不會替兩個 app 分 port、分 database、分 queue、分 credential,更不會決定 shared file 最後由誰改。
Git 還有一個保護機制值得知道:同一條 branch 預設不能同時被多個 worktree checkout;要繞過這個檢查必須明確使用 --force。[2]
Worktree 的隔離邊界停在 Git
linked worktree 不是另一個完整 repository,也不是一台新的 VM。
Git 官方文件把共享與獨立狀態分得很清楚:linked worktrees 共用同一個 repository 的共同資料與大部分 refs,repository configuration 預設也是共享的;HEAD、index 等特定檔案才屬於個別 worktree。[2]
因此兩個 Agent 就算檔案完全分開,仍可能一起使用:
localhost:3000
postgres://localhost/dev
redis://localhost:6379
其中一個 process 可能先占住 port;兩組 test 可能一起寫同一個 development database;Worktree A 啟動的 queue consumer 也可能吃掉 Worktree B 送出的訊息。
OpenAI 在 Harness Engineering 的案例裡,另外讓 app 可以針對每個 Git worktree 個別啟動,並為每個 worktree 建立短生命週期的 observability stack,讓 logs、metrics 與 traces 跟著工作空間分開。[5]
這些隔離是 Harness 額外補上的,範圍在 application instance 與 observability。Git worktree 本身沒有替 port、database、queue、credential 或外部 side effect 建立同樣的邊界。
如果一個 task 只改檔案,worktree 可能已經夠用。如果它會啟動 server、寫資料或碰外部資源,隔離設計就還沒結束。
兩個獨立施工現場,最後還是要收斂
把兩個 Agent 放到不同 worktree 後,施工期間乾淨很多:
Agent A -> Worktree A [branch: agent/payment-retry]
Agent B -> Worktree B [branch: agent/checkout-ui]
A 的 dirty files 不會突然出現在 B 的 working directory。
但如果兩邊最後都修改:
src/payment/config.ts
合併時仍然可能產生衝突。
AgenticFlict 收集了超過 142,000 個 AI coding agent 產生的 PR,其中超過 107,000 個進入 deterministic merge simulation;作者在這個資料集裡觀察到 27.67% textual conflict rate。[6]
這個數字不是 Codex benchmark,也不是兩個 worktree 發生衝突的機率。它只能支持一個比較窄的判斷:Agent 產生的 change sets 進入整合階段時,textual conflict 是需要被工作流處理的現實情況。

Figure 2|Worktree 把施工中的 working state 分開;兩組 change sets 匯合時仍需要 ownership、review、checks 與 merge。
PR 就是在這裡接手。
GitHub 的 PR 讓一條 head branch 對 base branch 提出變更,reviewer 可以檢查 diff、討論特定行、跑 checks,最後再決定是否 merge。[3] 它管理的是變更怎麼進入目標 branch,而不是替 Agent 提供另一份工作目錄。
可以把責任順序看成:
Worktree -> 產生實際修改
Branch -> 承載這條開發線
PR -> 提供 review 與整合入口
Base -> 接收被接受的結果
這不是 Git 強制規定的生命週期。worktree 裡的變更可以只留在本機,branch 也不一定要開 PR。這個順序只是用來避免把工作空間、版本線和整合流程混在一起。
先切清楚誰能改什麼,再決定要不要平行
worktree 能保護兩邊的 working state,卻不會判斷哪個 Agent 應該動 shared file。
如果 Task A 和 Task B 都需要大量修改同一個核心模組、同一份 schema migration 或同一個 shared config,硬拆成兩個 worktree 只是把衝突從施工期間延後到 merge。
派工前先把三件事寫清楚:
Target paths
Shared-file owner
Merge owner
例如:
Agent A
Target: src/payment/**
Shared file: config/payments.ts -> owned by A
Agent B
Target: src/checkout/**
Shared file: config/payments.ts -> do not edit
Merge owner
Integrates A + B and resolves the shared boundary
這不需要先搞一套完整的多 Agent 治理框架。目的只是先確認兩件工作是不是真的有足夠獨立性。
「任務小就不要開 worktree」這個規則很容易失準。Git 官方本身就把平行的實驗性工作列為 worktree 的典型用途。[2] 一個十分鐘的 hotfix,如果你現在的 main working tree 正堆著兩小時尚未 commit 的 refactor,額外 worktree 反而可能最省事。
判斷重點是隔離帶來的價值,值不值得支付多一份 workspace、同步與最後整合的成本。
| 情況 | 比較實際的做法 |
|---|---|
| 兩個 task 可以各自推進,而且都需要保留未提交狀態 | 分 worktree |
| 長時間 refactor 還沒收完,突然來一個獨立 hotfix | 即使 hotfix 很小,也值得考慮 worktree |
| 兩個 task 大量改同一批檔案或同一個 schema | 先重切 scope / ownership,或序列執行 |
| 只有一個很小、清楚的 edit,沒有 dirty state 要保留 | 單一 working tree 通常更直接 |
| 兩邊會啟動相同 service、共用 DB / queue / cache | worktree 之外再加 runtime / data 隔離 |
| repo 高度依賴 Git submodules | 先確認 worktree 相容性;Git 官方文件指出 multiple checkout 的 submodule 支援仍不完整,不建議直接對 superproject 做多重 checkout。[2] |
| 沒有人負責最後整合 | 先指定 merge owner,再 fan-out |
worktree 很適合解決「我需要另一份不互踩的施工狀態」,但不必變成每次叫 Agent 都要走的儀式。
下次開多個 Agent,先問四件事
遇到同一個 repo 要同時跑幾個 Codex task,可以快速檢查:
- History:每件工作最後由哪條 branch / commit line 承載?
- Working state:每個 worker 有自己的 worktree,還是大家共用同一個 directory?
- Integration:change set 在哪裡被 review、跑 checks、合進 base branch?
- Ownership:shared files 誰能改,最後誰負責 merge?
這四個問題拆開後,branch、worktree 和 PR 就各自回到自己的責任層。真正需要判斷的是工作怎麼切、哪些狀態仍然共用,以及什麼證據足以讓最後的變更安全收進主線。
References
- Git, Pro Git, 2nd Edition: Git Branching - Branches in a Nutshell. https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell
- Git, git-worktree Documentation. https://git-scm.com/docs/git-worktree
- GitHub Docs, About pull requests. https://docs.github.com/en/pull-requests/get-started/about-pull-requests
- OpenAI, Introducing the Codex app. https://openai.com/index/introducing-the-codex-app/
- OpenAI, Harness engineering: leveraging Codex in an agent-first world. https://openai.com/index/harness-engineering/
- Ogenrwot, D. & Businge, J., AgenticFlict: A Large-Scale Dataset of Merge Conflicts in AI Coding Agent Pull Requests on GitHub, arXiv:2604.03551. https://arxiv.org/abs/2604.03551