Give two Codex agents different branch names and put them in the same project directory. They still share the same checked-out files.
That is the first distinction to get right before running parallel coding tasks on one repository. A branch tells Git which line of development a name points to. A worktree gives a task another checked-out working directory, with its own HEAD, index and uncommitted state.[1][2]
Codex uses worktrees for the same practical reason. Its multi-agent app workflow supports separate copies of the code so agents can make progress on the same repository without all operating on one local Git working state.[4]

Figure 1 | Git, branches, worktrees and pull requests sit at different responsibility layers. This is an operating model, not an official Git taxonomy.
Start with the workspace, not the branch name
Consider two tasks:
Task A: refactor payment retry logic
Task B: update checkout UI
They can quite reasonably have separate branches:
agent/payment-retry
agent/checkout-ui
If both agents are launched in:
~/project/
there is still only one working tree underneath them.
A checkout by one process changes what is checked out in that directory. A reset, restore or index operation also acts on that shared state. Dirty files can block a branch switch altogether, forcing the workers to coordinate commits, stashes or clean-up before either can continue.
That is why the usual human intuition can be misleading. One developer often uses a working tree serially. Two agents can genuinely edit and execute at the same time.
The responsibilities are easier to see when laid out explicitly:
| Concept | What it answers | Main responsibility | It does not provide |
|---|---|---|---|
| Git | What repository history exists? | Commits, objects, refs and version data | Separate working directories |
| Branch | Where does this line of development point? | A movable commit reference | Another filesystem copy |
| Worktree | Where is this task’s checked-out state? | Another working directory with per-worktree HEAD, index and uncommitted state | A VM, container or complete runtime sandbox |
| Pull request | How should this change be reviewed and integrated? | Discussion, review, checks and merge on a hosting platform | A working copy or the branch itself |
Pro Git describes a branch as a lightweight movable pointer to a commit.[1] Creating one adds another reference. It does not duplicate the project directory.
A linked worktree operates on the working-state side of the problem. Git can attach multiple working trees to one repository while keeping repository data largely shared and selected state, including HEAD and the index, specific to each worktree.[2]
What a worktree actually buys you
The earlier example can be separated like this:
~/project/ -> main worktree
~/project-payment/ -> agent/payment-retry
~/project-checkout/ -> agent/checkout-ui
One of those linked worktrees could be created with:
git worktree add ../project-payment -b agent/payment-retry main
The command gives the payment task another working directory in which it can check out files, edit them and keep uncommitted changes without sharing that exact working state with the checkout task.[2]
Git also prevents an easy source of confusion. By default, it will not check out the same branch in more than one linked worktree; overriding that safeguard requires an explicit force option.[2]
Nothing in the command isolates the rest of the development environment. Two worktrees can still point at the same resources:
localhost:3000
postgres://localhost/dev
redis://localhost:6379
Separate files do not stop one process taking the port, two test suites writing to one database, or one queue consumer handling work created by the other task.
OpenAI’s harness-engineering account is a useful example of the extra layer involved. The team made its application bootable per Git worktree and provisioned an ephemeral observability stack for each worktree so logs, metrics and traces could be scoped to the task.[5]
Those are application-instance and observability boundaries added by the harness. They are not properties supplied by Git worktrees themselves. A task that starts services or mutates shared external state may therefore need separate ports, data stores, credentials, queues or other environment controls as well.
The integration bill still arrives
Worktrees improve the implementation phase because dirty state from Agent A no longer appears in Agent B’s directory:
Agent A -> Worktree A [branch: agent/payment-retry]
Agent B -> Worktree B [branch: agent/checkout-ui]
The two change sets can still meet on the same lines later.
If both agents edit:
src/payment/config.ts
Git may have to reconcile those changes during integration.
AgenticFlict gives some scale to that problem. Its dataset contains more than 142,000 pull requests produced by AI coding agents; more than 107,000 went through deterministic merge simulation, and the authors report a 27.67% textual conflict rate in that dataset.[6]
This is not a Codex benchmark and it is not the probability that two Codex worktrees will conflict. It is evidence from one external dataset that agent-generated change sets can create non-trivial integration conflicts.

Figure 2 | Separate worktrees protect working state during implementation. Ownership, review, checks and merge still matter when the change sets converge.
A pull request belongs on this side of the workflow. On GitHub, a PR proposes changes from a head branch to a base branch and gives reviewers a place to inspect the diff, discuss lines, run checks and decide whether to merge.[3]
The responsibilities line up like this:
Worktree -> produces the working changes
Branch -> carries the line of development
PR -> presents the change for review and integration
Base -> receives the accepted result
Git does not require every worktree to end in a PR, and a branch can exist without one. The chain is simply a way to keep working state, development history and integration policy from being collapsed into the same concept.
Parallelism only pays when ownership is clear enough
Two worktrees are a poor bargain if both agents need to rewrite the same core module, migration or shared configuration.
A small dispatch check can expose that problem before fan-out:
Target paths
Shared-file owner
Merge owner
For example:
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
Three fields are enough for this decision. They expose whether the tasks have a clean enough boundary to benefit from parallel execution; the wider governance problem can wait.
Task size is a poor shortcut for the same decision. Git’s own worktree documentation includes temporary and experimental work as normal uses.[2] A ten-minute hotfix can justify another worktree when the main directory contains hours of unfinished refactoring that you do not want to disturb.
Use the isolation value, rather than the size label, to decide:
| Situation | Practical choice |
|---|---|
| Two tasks can progress independently and both need persistent uncommitted state | Use separate worktrees |
| A dirty long-running refactor is active and an independent hotfix arrives | A worktree may be worthwhile even for the small task |
| Both tasks must rewrite the same files or schema | Redesign scope or ownership first, or work serially |
| One small edit has no dirty state to preserve | One working tree is usually simpler |
| Both tasks start the same services or mutate the same database, queue or cache | Add runtime/data isolation as well as worktrees |
| The repository relies heavily on Git submodules | Check worktree compatibility first. Git documents incomplete submodule support for multiple checkouts and does not recommend multiple checkouts of a superproject.[2] |
| Nobody owns final integration | Name the merge owner before fan-out |
The extra directory, coordination and eventual merge are costs. They are worth paying when they remove a more expensive shared-working-state problem.
Before you fan out, answer four questions
Before launching several Codex tasks against one repository, four questions catch most of the conceptual mistakes:
- History: which branch or commit line will carry each task?
- Working state: does each worker have its own worktree, or are several workers sharing one directory?
- Integration: where will the change set be reviewed, checked and merged into the base branch?
- Ownership: who may edit shared files, and who owns the final merge?
Once those answers are explicit, the Git mechanics become much less mysterious. The harder questions are the ones worth spending time on: whether the work is independent enough to parallelise, what state still remains shared outside Git, and what evidence is required before the resulting changes enter the main line.
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