Skip to content

Worktree Isolation

hypnguyen1209 edited this page Aug 25, 2026 · 1 revision

Worktree Isolation

In multi-project mode, two ChatGPT conversations can select the same Git project. Without care, they'd edit the same working tree and clobber each other. Managed worktrees solve this: each conversation beyond the first gets its own detached checkout, so concurrent chats never share a working tree.

This applies only in Multi-Project Mode and only to Git projects. Non-Git projects and single-project mode are unaffected.


The three modes

Set with --worktree-mode or worktrees.mode:

Mode Behaviour
auto (default) The first conversation to select a Git project uses the source checkout directly. Once that logical project is assigned, another conversation receives a detached managed worktree.
always Every conversation gets its own managed worktree — even the first.
never Direct-checkout sharing is preserved; no managed worktrees are created.

How a project's identity is determined

Worktree identity uses the repository's Git common directory plus the selected path relative to its Git root. So:

  • Linked worktrees of the same repo are recognized as the same project.
  • Separate subprojects in a monorepo (e.g. packages/app vs packages/other) remain distinct.

Where worktrees live

The parent directory comes from, in order: worktrees.root--worktree-root → Codex Desktop's git-worktree-root in $CODEX_HOME/config.toml$CODEX_HOME/worktrees (normally ~/.codex/worktrees).

Upstream refresh

worktrees.upstreamRefreshMode:

  • never (default) — don't touch the upstream.
  • best-effort — refresh a tracked upstream before creating the worktree, without making a fetch failure fatal.

When unset, Codex Free reads Codex Desktop's worktree-upstream-refresh-mode.

Cleanup

On startup Codex Free sweeps old managed worktrees:

  • autoCleanupEnabled (default true) — remove old unreferenced worktrees only when their working trees are clean.
  • keepCount (default 15) — retain this many newest unreferenced managed worktrees before considering the rest as cleanup candidates.

Cleanup skips referenced or dirty worktrees. A managed worktree stays referenced while its conversation binding exists — so deleting a binding (under ~/.codex-free/conversation-projects/) is what eventually makes its worktree a cleanup candidate.

The setup-script gate (read this)

worktrees.allowSetupScript defaults to false, and you should almost always leave it there.

A worktree can have a Codex environment setup script that runs on creation. That script:

  • runs an arbitrary command outside the allowedCommands / exec policy, and
  • has both its environment file and script path selectable from the source repository's local Git config.

So an untrusted project could plant a script that runs on the next binding. Only enable this if every project reachable by this server is trusted to run arbitrary setup commands. See Security Model.


Configuration summary

{
  "worktrees": {
    "mode": "auto",
    "root": "/path/to/worktrees",
    "upstreamRefreshMode": "never",
    "autoCleanupEnabled": true,
    "keepCount": 15,
    "allowSetupScript": false
  }
}

CLI equivalents: --worktree-mode, --worktree-root. Full table in Configuration.


See also

Clone this wiki locally