Isolated Codex tasks with Git worktrees
PLA Codex worktree task runs one session in its own Git worktree, so its edits, installs and tests never touch your main checkout. Codex CLI 0.157.1 creates a managed worktree with --worktree or /worktree; git worktree add lets you name the path and branch. It is finished only when its gates pass and its commits sit on a branch.
You asked Codex to fix a flaky auth test while you kept working on a migration in the same directory. Twenty minutes later your working tree holds both sets of changes, npm install has rewritten the lockfile under you, and you cannot tell which edits are yours. This page is for the developer who runs Codex locally and wants every task in its own checkout, with a clean way to verify it, keep it and throw it away.
What you get from running Codex tasks in worktrees
Section titled “What you get from running Codex tasks in worktrees”- A decision table for managed worktrees (
codex --worktree), explicit ones (git worktree add) and the desktop app. - The facts about what a managed worktree does and does not carry over, measured on Codex CLI 0.157.1.
- A bootstrap script that makes a fresh worktree runnable without copying production secrets.
- Two copy-paste prompts: one that starts a task safely inside a worktree, one that hands it back ready to merge.
- A gate you run before you read any diff, and a cleanup order that never deletes an unmerged commit.
Coordinating many worktrees at once (lanes, fan-out scripts, merge order) is the job of Codex multi-agent workflows. This page covers one task’s worktree from creation to removal.
Which kind of Codex worktree should you use?
Section titled “Which kind of Codex worktree should you use?”Worktree support is on by default since Codex CLI 0.156.0 (the worktrees feature is stable and true in codex features list, 0.157.1). A session still runs in your current directory unless you opt in. Codex 0.162.0 (2026-10-08) added managed Git worktree tools that create and list worktrees from trusted projects (OpenAI’s release notes). The carry-over measurements in the next section were taken on 0.157.1, and the release notes do not say whether the carry-over changed, so repeat that check after you upgrade.
| You want | Use | Where the checkout lives | Branch |
|---|---|---|---|
| A quick isolated interactive task | codex --worktree | $CODEX_HOME/worktrees/<id>/<repo> (by default under ~/.codex/) | None: detached HEAD at your current commit |
| To move a running conversation into isolation | /worktree inside the session (“start or continue a conversation in a new worktree”) | Same managed location | None until you create one |
| A scripted, non-interactive task | codex exec --worktree, or git worktree add plus codex exec -C DIR | Managed location, or a path you choose | None with codex exec --worktree (detached HEAD); named with git worktree add -b |
| A path, branch and base you control (ports, CI scripts, review tooling) | git worktree add -b BRANCH PATH BASE, then codex in that path | Where you put it | Named from the start |
| Threads in the desktop app | The app’s worktree option per thread (codex app, macOS and Windows) | Managed by the app | See Codex desktop app mastery |
codex fork --worktree and codex resume --worktree exist too (checked in --help, 0.157.1): they continue an earlier session in a new managed worktree, which is the clean way to try a second approach without disturbing the first.
The rule of thumb: use --worktree for throwaway or exploratory tasks, and git worktree add when the result must become a named branch and pull request, or when a script, a port allocator or a teammate needs to find the checkout by path.
What does a managed Codex worktree carry over?
Section titled “What does a managed Codex worktree carry over?”We ran codex exec --worktree on Codex CLI 0.157.1 (2026-09-26) in a repository with a modified tracked file, an untracked file and a gitignored .env. The managed worktree contained:
| State in your main checkout | In the managed worktree? |
|---|---|
Committed files at HEAD | Yes, checked out at the same commit |
| The current branch | No. The worktree is on a detached HEAD |
| Uncommitted edits to tracked files | No. The file has its committed content |
| Untracked files | No |
Gitignored files (.env, node_modules/, build caches) | No |
Three consequences follow. Commit (or stash and re-apply) anything the task depends on before you start it. Expect every managed worktree to need a dependency install and local configuration. Create a branch before the agent commits, because commits on a detached HEAD belong to no branch and are easy to lose when the worktree is removed.
The managed worktree also outlives the session: in the same run it was still listed by git worktree list after codex exec exited. codex --help in 0.157.1 lists no subcommand that removes a worktree, so removal is Git’s job, from any checkout of the repository.
Run one Codex task in an isolated worktree
Section titled “Run one Codex task in an isolated worktree”-
Check what the task will start from.
Terminal window git status --short # anything listed here will NOT reach a new worktreegit branch --show-currentgit worktree list # existing worktrees, including Codex-managed onesCommit the work the task needs. If you do not want to commit half-finished code, create the worktree from the last good commit and describe the missing piece in the prompt instead.
-
Create the worktree. Pick one of the two forms.
Managed, for a quick task:
Terminal window codex --worktreeThe session opens in
$CODEX_HOME/worktrees/<id>/<repo>; in a second terminal, find it withgit worktree listand run the bootstrap there before you send the first prompt.Explicit, when you want the branch and path fixed up front:
Terminal window git fetch origingit worktree add -b codex/fix-auth-flake ../myapp-fix-auth-flake origin/maincd ../myapp-fix-auth-flakecodexReplace
origin/mainwith your repository’s real default branch (git symbolic-ref refs/remotes/origin/HEADprints it). Git refuses a branch that is already checked out in another worktree, which is a feature: two agents cannot share one branch by accident. -
Bootstrap the checkout. Run this from inside the new worktree, in your own terminal rather than through the agent, so installs get the network access the sandbox withholds:
#!/usr/bin/env bash# bootstrap-worktree.sh: make a fresh worktree runnableset -euo pipefailMAIN=$(git worktree list --porcelain | awk 'NR==1 {print $2}') # the main checkout is always listed firstfor f in .env.development .env.test; do # development files only, never productionif [ -f "$MAIN/$f" ]; then cp "$MAIN/$f" .; fidonenpm ci # install from the lockfile, do not re-resolvegrep -qs '^PORT=' .env.development || echo "PORT=$((4000 + RANDOM % 1000))" >> .env.development # a port no other worktree is likely using; added onceRe-running the script is safe: it copies the same files again, reinstalls from the lockfile and keeps the port it already assigned. Keep an allowlist of files to copy, as above. Copying every gitignored file is how a production key ends up in a directory an agent can read. If your repository already has a setup script, call it here instead. When the task also needs its own database or service stubs, give it a full per-task stack as in ephemeral environments for agent tasks.
-
Start the task with a scoped prompt. Paste the first prompt below. It tells Codex where it is, what it may touch and what “done” means.
-
Prove the result before you read it. Run the gate in How do you verify a worktree task without reading every line? below. Read the diff only when the gate passes, and then only the files it flags.
-
Integrate through the normal path. Push the branch and open a pull request, so CI and your review rules apply exactly as they do to human work. Do not copy files between worktrees by hand, and do not
git applyseveral agent patches onto one branch without rerunning the gates after each. -
Remove the worktree only after the work is safe. See clean up Codex worktrees without losing commits.
Adjust the test file, paths and repeat command to your project; the structure (locate, branch, rules, a done condition with exit codes) is what makes the prompt work in any worktree.
How do you verify a worktree task without reading every line?
Section titled “How do you verify a worktree task without reading every line?”A worktree gives you something the shared checkout never does: a diff that belongs to exactly one task. Use it. Run these checks from the task’s worktree, in order, and stop at the first failure.
#!/usr/bin/env bash# worktree-gate.sh BASE ALLOWED_PATHS_REGEX# example: ./worktree-gate.sh origin/main '^(src/auth/|tests/auth/)'set -euo pipefailbase="$1"; allowed="$2"
test -z "$(git status --porcelain)" || { echo "FAIL: uncommitted changes"; exit 1; }git symbolic-ref -q HEAD >/dev/null || { echo "FAIL: detached HEAD, create a branch"; exit 1; }
stray=$(git diff --name-only "$base"...HEAD | grep -v -E "$allowed" || true)[ -z "$stray" ] || { echo "FAIL: files outside the task:"; echo "$stray"; exit 1; }
npm run typecheck # separate lines: set -e stops on the first failing checknpm run lintnpm test
codex review --base "$base" || echo "WARN: codex review did not complete" # advisory: findings never fail the scriptecho PASScodex review --base runs the built-in review prompt. In Codex CLI 0.157.1 it cannot take custom instructions as well: codex review --base main "..." fails with the argument '--base <BRANCH>' cannot be used with '[PROMPT]' (checked 2026-09-26), and --uncommitted has the same restriction. Put standing review rules, such as “flag behaviour without a test”, in AGENTS.md instead of on the command line. codex review is advisory in this script: it prints findings, and codex review --help in 0.157.1 documents no exit code that fails on them, so a PASS line means the mechanical checks passed. If the review cannot run at all (not signed in, no network), the || echo prints a warning instead of letting set -e stop the script. Read its output, and treat the files it flags as the ones you read by hand.
| Check | What it catches |
|---|---|
| Clean status and a named branch | Work that exists only in the worktree and would vanish on removal |
| Allowed-paths diff | An agent that “fixed” something outside its task |
| Type check, lint, tests | Broken behaviour, run in isolation from other tasks’ edits |
codex review --base | Logic errors and missing tests, from a second pass that did not write the code |
| CI on the pull request | Everything above again, on a clean machine, plus integration with the latest base |
You sign off on two things: the done condition in the prompt before the task starts, and the files the gate flags afterwards. Auth, payments and migrations always get a human read, whatever the gate says. The done condition works best as an executable acceptance criterion (how to turn acceptance criteria into failing tests), and the pull request should carry the evidence bundle an agent’s pull request must prove. For how review scales across a team, see Codex review strategies.
Clean up Codex worktrees without losing commits
Section titled “Clean up Codex worktrees without losing commits”Every task leaves a checkout, and a managed one sits under $CODEX_HOME/worktrees/ where you will not notice it filling the disk. Clean up in this order:
git worktree list # find the path, including managed onesgit -C PATH status --short # must be emptygit -C PATH log --oneline BASE..HEAD # commits not yet on the basegit branch -r --contains "$(git -C PATH rev-parse HEAD)" # empty output = not pushed anywheregit worktree remove PATHgit worktree prune # drop records of worktrees deleted by other meansPATH is the worktree’s directory from git worktree list, and BASE is the branch the task started from, such as origin/main. git worktree remove refuses a worktree with modified or untracked files. Add --force only after the status and log checks show there is nothing you want, because it deletes those files for good. Delete the branch last, with git branch -d (which refuses unmerged branches), not -D.
When Codex worktree tasks go wrong
Section titled “When Codex worktree tasks go wrong”| Symptom | Cause | Recovery |
|---|---|---|
| The agent reports missing modules or config on its first command | Managed and new worktrees get no gitignored files | Run the bootstrap script, then restart the task |
| The task ignores a fix you made minutes ago | The worktree starts from the last commit, not your working tree | Commit the fix, then codex fork --worktree or start again |
| Commits disappeared after cleanup | The agent committed on a detached HEAD; git worktree remove does not refuse that, and it deletes the worktree’s own reflog | Before Git garbage-collects them, list orphaned commits with git fsck --lost-found, find yours with git show SHA, then git branch rescue/TASK SHA. Prevent it with the branch step in the first prompt and the gate’s named-branch check |
| Git reports the branch is already used by (or checked out in) another worktree | The branch is checked out in another worktree | Use a new branch name, or remove the other worktree first |
The agent cannot commit, or asks for approval on every git write | A worktree’s Git metadata lives in the main repository’s .git/, which can sit outside the sandbox’s writable area | Commit from your own terminal, or make that directory writable deliberately with --add-dir (see permissions and sandboxing) |
| Codex says “The new worktree is not trusted; run Codex there.” | The new checkout path has not been marked as trusted, and untrusted projects do not supply AGENTS.md (since Codex CLI 0.150.0) | Run codex in the worktree, accept the trust prompt only for a repository you trust, then restart the task so it reads AGENTS.md |
| Two dev servers fight over one port | Every worktree inherited the same PORT | Give each worktree its own port in the bootstrap step and pass it to the dev server and end-to-end tests |
| Two tasks’ changes conflict at merge | Both touched a shared file (router, barrel export, schema) | Merge one, rebase the other on it, rerun the full gate. Next time, split tasks by file ownership as in multi-agent workflows |
| The disk fills up | Every worktree holds its own dependencies and build output, and managed worktrees stay after the session ends | Remove finished worktrees weekly with the cleanup sequence above |
Where to go next with Codex worktrees
Section titled “Where to go next with Codex worktrees”- Before this page: configure Codex and write
AGENTS.mdfor Codex, so every worktree knows its build and test commands. - Next: Codex multi-agent workflows to run several worktree tasks as parallel lanes, and non-interactive Codex with
codex execto script them. - For tasks too heavy for a laptop: Codex cloud environments.
- The same isolation in Claude Code and Cursor: running parallel agents in isolated worktrees, and tools that manage many at once in parallel agent tools.