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]

Responsibility map for Git, branches, worktrees and pull requests

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:

ConceptWhat it answersMain responsibilityIt does not provide
GitWhat repository history exists?Commits, objects, refs and version dataSeparate working directories
BranchWhere does this line of development point?A movable commit referenceAnother filesystem copy
WorktreeWhere is this task’s checked-out state?Another working directory with per-worktree HEAD, index and uncommitted stateA VM, container or complete runtime sandbox
Pull requestHow should this change be reviewed and integrated?Discussion, review, checks and merge on a hosting platformA 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.

Parallel agents using separate worktrees before converging at an integration boundary

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:

SituationPractical choice
Two tasks can progress independently and both need persistent uncommitted stateUse separate worktrees
A dirty long-running refactor is active and an independent hotfix arrivesA worktree may be worthwhile even for the small task
Both tasks must rewrite the same files or schemaRedesign scope or ownership first, or work serially
One small edit has no dirty state to preserveOne working tree is usually simpler
Both tasks start the same services or mutate the same database, queue or cacheAdd runtime/data isolation as well as worktrees
The repository relies heavily on Git submodulesCheck worktree compatibility first. Git documents incomplete submodule support for multiple checkouts and does not recommend multiple checkouts of a superproject.[2]
Nobody owns final integrationName 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:

  1. History: which branch or commit line will carry each task?
  2. Working state: does each worker have its own worktree, or are several workers sharing one directory?
  3. Integration: where will the change set be reviewed, checked and merged into the base branch?
  4. 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

  1. Git, Pro Git, 2nd Edition: Git Branching - Branches in a Nutshell. https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell
  2. Git, git-worktree Documentation. https://git-scm.com/docs/git-worktree
  3. GitHub Docs, About pull requests. https://docs.github.com/en/pull-requests/get-started/about-pull-requests
  4. OpenAI, Introducing the Codex app. https://openai.com/index/introducing-the-codex-app/
  5. OpenAI, Harness engineering: leveraging Codex in an agent-first world. https://openai.com/index/harness-engineering/
  6. 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