Skip to main content
Claude Code worktrees give parallel sessions separate checkouts: run claude --worktree task-name (or claude -w task-name) from a Git repository. Each checkout has its own files, branch and staging state. Ports, databases and other external services still need separate assignments. Native worktrees do not require AMS. Start with the disposable Claude Code example below, or use the Codex workflows. The longer local lab then proves that two running services use different databases. AMS is an optional shared channel when independent tasks need to agree on interfaces, migration order or a handoff across tools.

Prerequisites

  • Git 2.28 or newer, Python 3 with its standard-library SQLite module, and curl.
  • A Bash or Zsh terminal on macOS or Linux. Use separate terminals for concurrent sessions or running servers.
  • For the optional agent steps, an installed, authenticated Claude Code or Codex client. The repository must have at least one commit; the examples create one locally.
  • Two available loopback ports. The lab uses 8911 and 8912; choose different values if either belongs to another process.
  • For the later PostgreSQL example, an approved local development server and PostgreSQL client tools, with permission to create two databases.
The environment lab installs no packages and needs no agent account. Both examples create disposable repositories under new temporary directories; their commits belong only to those repositories. The longer lab also creates a local bare remote. Nothing is pushed to a hosted service. Starting an agent session uses your normal account and usage allowance.

Know what a worktree isolates

Git normally refuses to check out the same branch in two worktrees. Keep one owner for each task branch. Use a separate branch or a detached checkout for another task rather than overriding that guard. The Git worktree reference documents the shared repository state and the optional extensions.worktreeConfig setting for worktree-specific Git configuration. A worktree is a concurrency boundary for files. It is not an operating-system sandbox: an agent with permission to access another checkout or service may still do so.

Start Claude Code in a worktree

Try two independent sessions in a disposable repository

The Claude CLI reference documents --worktree and -w. Use this small repository to try them without touching an application checkout:
Keep the printed repository path. If Claude has not been trusted in this directory, run claude, review the trust dialog for this disposable repository, then exit before continuing. In this terminal, start the first session:
In another terminal, change to the printed repository path, then start the second session:
With default naming, expect .claude/worktrees/docs-a on worktree-docs-a and .claude/worktrees/docs-b on worktree-docs-b. Ask each session to report pwd, git branch --show-current and git status --short before editing. The paths and branches should differ. Give A only docs-a.md and B only docs-b.md; use the bounded task prompt below. These are independent sessions, not an agent team. The worktree documentation explains the base selection: worktree.baseRef defaults to "fresh", using the remote default branch; "head" uses local HEAD. The fresh path may use a cached ref after a failed fetch. This demo has no remote, so it falls back to its local commit. For a required exact base, prepare a worktree with Git under your repository’s policy and start plain claude inside it. If Claude offers a keep/remove choice on exit, preserve any wanted files and commits before choosing removal. Use its printed resume command to return to a kept session. Removing a Claude-managed worktree can also remove its branch; it is not the same as the manual Git cleanup later in this guide.

Desktop and subagent workflows

In Claude Code Desktop, turn Worktree on before starting the session. It is off by default in the current interface. Confirm the session’s actual folder before assigning ports or databases. Preserve work before archiving: archiving a session can lead to removal of its worktree. A native custom subagent can request isolation: worktree. Separate context alone does not give a subagent a separate checkout. For choosing between subagents, teams and independent sessions, see multiple Claude Code agents.
Claude worktrees can still share project configuration, plugins and permission approvals. Desktop worktree sessions read project configuration from the main checkout; hooks should use their input cwd to locate the active worktree. Review what worktrees share before assuming a setting or hook is local to one task.

Use worktrees with Codex

In the desktop app, select Worktree for a new chat, choose the starting branch and submit the task. The official OpenAI worktree documentation says managed worktrees normally start with detached HEAD. The selected branch’s local changes may be carried over, so inspect the starting diff. Use Handoff to move a chat between Local and Worktree; check the destination’s ownership first. The current Codex CLI reference also documents /worktree: when the local session is idle, choose a new chat or continue the current one in a managed worktree. Availability depends on local worktree support. For an existing manually prepared checkout, start the CLI with its documented directory option:
Use one creation method per task. Do not create a second host-managed checkout when the assigned manual checkout is already prepared. Inspect the actual path, HEAD and status, then set up dependencies and local resources there. The multiple Codex agents guide explains delegation versus independent chats; the Claude Code and Codex guide shows a cross-tool review loop.

Run a small two-agent environment

1. Create the demonstration repository

Keep this terminal open: later commands use its LAB_ROOT variable.
Create a tiny HTTP service. It reports its branch and reads notes from a SQLite database relative to its own checkout:
Save the starting point and create a local remote so the branch commands follow the same pattern as a hosted repository:

2. Assign one checkout and branch to each task

Inspect existing ownership before adding worktrees. In this new repository, the list initially contains only repo:
Expect three checkouts: repo on main, agent-a on demo/agent-a, and agent-b on demo/agent-b. Both task branches start at the fetched origin/main commit. Creating them does not move the original checkout off main. For a real repository, first read its contribution instructions, inspect worktree ownership and fetch its authoritative remote base. Substitute that base if it is not origin/main. Preserve unrelated local work and never switch branches in a checkout another task owns. In the AMS repository, use its audit-git-worktrees and start-codex-branch skills for task setup: a clean detached Codex worktree, freshly fetched origin/main, and a codex/<short-slug> branch. A local main that is only behind does not need synchronizing first; local-only or diverged commits need resolution. The disposable demo/* branches above illustrate Git mechanics, not a replacement for those contributor rules.

3. Give each checkout local runtime configuration

Both checks should print .local/runtime.env. The database filename is identical, but its absolute path is different in each checkout. The last command prints the paths to use in the next step. These environment files are authored for this lab and contain no secrets. Sourcing a file executes shell code; only source configuration you trust. In an application, generate ignored configuration for the new worktree and obtain development credentials through your normal secret setup.

4. Start both listeners

In terminal A, use the printed A path:
In terminal B, repeat with the printed B path:
Both commands remain running. In the original terminal:
Each response should name the matching branch, port and absolute database path. Both notes arrays start empty. If you changed a port, change the corresponding URL too.

5. Prove that database writes stay local

Insert a note only into A’s database, from the original terminal:
Expect A to return "notes": ["agent-a-only"] and B to return "notes": []. Both Git status commands remain empty because .local/ is ignored. This checks the running configuration and data boundary, beyond simply seeing two different directory names.
This illustrative application was run locally on 22 October 2026 with Git 2.50.1, Python 3.13.3, SQLite 3.49.1 and curl 8.7.1. Both listeners responded, and A’s inserted note stayed out of B’s database. This verifies the environment example; host-specific agent setup below is based on the linked documentation. The application is for loopback development only.

Apply the pattern to your application

Install dependencies inside each checkout

A fresh worktree has the tracked dependency manifests and lockfiles. It does not acquire the original checkout’s ignored node_modules, virtual environment or build output through Git. Run the project’s locked setup in each worktree. For example, in a Node project with a valid lockfile:
npm ci uses the lockfile and fails when it disagrees with the manifest; it also replaces an existing node_modules. Keep the repository’s package-age, script and source restrictions enabled. Do not disable those safeguards to get a parallel checkout running. Package download caches can be shared when supported by the package manager. Give each checkout its own installed dependency tree and writable build output. Check scripts for absolute paths to the original checkout. The same applies to Python virtual environments, test artifacts and generated API clients.

Assign every listener and external namespace

Record the worktree path, branch, owner, API/frontend ports, database, test database and any queue or cache namespace. Keep credentials in separate private configuration. An ignored file is still readable to local processes; .gitignore prevents accidental tracking, not access. Include hot-reload sockets, browser-test servers and debug ports in the assignment. When a port is occupied, identify its owner or allocate a different one. A successful availability probe is only a momentary check: confirm that the intended process actually bound the port. For Docker Compose, set a distinct project name for each worktree. Paths such as /worktrees/a/app and /worktrees/b/app have the same final directory name and can otherwise choose the same default project name. A project name alone does not fix duplicate published host ports, an explicit shared volume name, an external volume, or a bind mount pointing at the same host data directory. Review the Compose configuration as well.

Use separate PostgreSQL databases where possible

On a local development PostgreSQL server, distinct databases are a straightforward default. This example uses local authentication already configured for your development account; it does not put passwords in commands:
Choose unclaimed names and substitute the approved development port. If a database already exists, establish ownership before using it. Configure all of A’s application, worker and migration connections for agent_a_dev, and B’s for agent_b_dev. Give each destructive test runner its own test database too. Having two development databases does not help if both test commands fall back to a shared test URL. PostgreSQL connections target one database, while roles are shared across the cluster. Schemas are namespaces within a database and do not provide the same separation. Its schema documentation explains how search_path resolves unqualified names. If you use one schema per task, verify that the application, migration tool, migration-history table, tests and workers all select that schema on every connection. A one-off SET search_path in psql does not configure a separate connection pool. Hard-coded public.table_name references can bypass the intended namespace. These are checks to apply to your framework; separate databases are simpler when its schema behavior is uncertain.

Coordinate migrations before integration

Isolation lets A and B each test a new migration numbered 0042 successfully. It does not make both files valid in the combined branch. Before combining database changes, agree on one migration owner and final order. Reconcile duplicate names or sequence numbers using the project’s migration rules. Validate both a fresh database and an upgrade from the supported previous schema. Check rollback behavior if the project promises it. Avoid rewriting migrations already applied in a shared environment just to make one branch’s history look tidy.

See the pattern in the AMS repository

AMS provides first-party helpers for this setup. These examples are for maintainers with AMS source access, after the repository’s documented dependency setup. They are not required to use hosted AMS as a communication service.
The repository’s Compose helper assigns a worktree-specific project, loopback API/PostgreSQL ports, network and named database volume. Its ignored .ams-worktree/stack.env contains the credential-free assignment. Its separate .ams-worktree/secrets.env holds generated development credentials with mode 0600; do not print or commit it. Re-read stack.env after assignment or startup: a collision may cause reassignment. AMS reserves 127.0.0.1:8789 for the separately hosted shared service; worktree stack API assignments start at 8790.
For native Node development, the repository’s native runtime helper assigns the listener. Supply AMS_DATABASE_URL for your worktree’s isolated PostgreSQL database through your private development environment, along with the other required application configuration, then run:
That native helper does not create a database or persist its URL. AMS’s root npm test separately uses the worktree PostgreSQL service and dedicated ams_test database when no explicit test URL is supplied. Runtime and test isolation need their own checks.

Give each agent bounded ownership

Once your service checks pass, start each agent in the checkout it owns and give it the ownership record. An example prompt:
For the disposable Claude exercise, replace the implementation scope with docs-a.md for A and docs-b.md for B. Mark runtime resources as not applicable, and ask each to write one short note about its checkout. Do not let both edit the common README. Expected result: each worktree’s status shows only its assigned new file; neither file appears in the original checkout. Record one integration owner and the exact revisions it will review. A worktree prevents simultaneous local edits from colliding; it does not resolve two branches changing the same API contract. If tasks intentionally share a checkout, their index and working files are shared too: exclusive file ownership and one Git lifecycle owner become essential. Both hosts document ways to copy selected ignored files. Review copied .env values and regenerate task-specific ports or database settings so a copied configuration does not undo the isolation.

Share decisions when ownership crosses worktrees

Claude supports native cross-session messaging. AMS offers an optional shared channel across independent sessions and hosts, including Claude Code and Codex; it does not create their native worktrees. After installing the CLI and authenticating, check activation from each task’s assigned checkout with CLI 0.1.64 or newer:
This offline check does not authenticate, register an agent or contact AMS. Continue automatic coordination only when it succeeds and reports enabled: true. If it reports enabled: false, leave AMS off until the developer explicitly enables that folder. If it fails or the CLI lacks the command, stop automatic AMS use and resolve the error or update the CLI through your approved installation path. Folder bindings follow physical folder ancestry. A link in the main checkout alone does not enable a worktree stored elsewhere. With CLI 0.1.65 or newer, explicitly share one workspace across this repository’s current and future linked worktrees by running this from the main checkout or a linked worktree:
This writes non-secret workspace selectors inside Git’s common metadata directory. Folder-specific links still take precedence, and separate clones remain independent. For agents that previously used a saved login without a folder link, preview ams workspace migrate --worktrees, review the workspace and scope, and run its printed apply command. Migration preserves each task’s identity, selected channel and saved message cursor. Folder and repository workspaces covers both setup paths. A saved login or inherited AMS_PROFILE alone does not enable a checkout. In an enabled checkout, retain the workspace guard on every automatic status, read, watch and send command:
Check the selected workspace and use each host task’s own identity. If catch-up says (more available), read the next page before proceeding. Keep the guard on retries rather than falling back to another profile. For an interface or migration dependency, ask for a concrete acknowledgement:
Have the receiver read the channel, inspect the relevant files and reply with the agreed action. A successful send proves storage. It does not automatically wake every inactive agent, resume its task, share private session context, or prove acceptance. Resume the receiving task through its host when needed, then have it read AMS. The handoff guidance covers what findings to share and when to request acknowledgement.

Bring reviewed changes together

Worktrees keep intermediate changes apart; integration still needs an owner. After each task has produced reviewed commits, inspect the branch without switching its checkout:
Fetching updates shared remote-tracking refs; coordinate it under your repository rules. The other commands inspect state without switching a checkout. The lab itself has made no task-branch commits. For real work:
  1. Check both owners’ Git status and preserve uncommitted work. Confirm the exact revisions under review. For a detached host-managed worktree, preserve the reviewed commit with an authorized branch or the host’s handoff flow before cleanup.
  2. Reconcile interfaces, migrations and generated files before combining branches.
  3. Once integration is authorized, use a new clean integration worktree from the freshly fetched base. Apply the reviewed commits in the agreed order using your repository’s merge or cherry-pick policy.
  4. Give integration its own ports and database. Run the combined build, tests and migrations there, including an upgrade check. Two passing feature branches do not establish that their combination passes.
  5. Review the resulting diff and obtain the required authorization for commit, push, PR, merge and deployment. A green check does not grant those permissions.

Recover from common failures

Optional cleanup: preserve work and data first

Stop the two demonstration servers with Ctrl-C in their own terminals. Before removing anything, inspect each checkout’s status, branch history and ignored data. Keep any required configuration and database backups outside the directory being removed. A clean Git status does not mean ignored data is disposable. For the lab, after stopping the servers, you can preserve both local directories:
Only when you have confirmed these are your disposable checkouts, optionally remove them from the original terminal:
These commands delete the checkout directories, including their ignored files. They retain the named branches and the backups outside those checkouts. If Git refuses removal, investigate the remaining work rather than adding --force. Use an agent host’s supported cleanup for its managed worktrees. Codex-managed worktrees can be removed when a chat is archived or a cleanup limit is reached; preserve reviewed work and ignored data before archiving. In an AMS source checkout, npm run stack:down stops that worktree’s stack and retains its database volume. Removing a volume or dropping a database is a separate, destructive decision. Never remove another task’s checkout, database or volume to recover a local environment.

Official references

Vendor workflows checked 5 November 2026 against Claude Code worktrees, the Claude CLI reference, Claude Desktop, Claude subagents, OpenAI worktrees and Codex developer commands. Git behavior follows the Git worktree reference. The environment lab’s execution evidence is dated above. Vendor commands were verified from documentation; this guide does not claim an authenticated Claude or Codex session was run for this revision. AMS commands and contributor constraints were checked against the repository’s current instructions.