Skip to content
September 9, 2026

Git worktrees: the isolation layer for parallel AI agents

A git worktree is an additional working directory attached to an existing repository. It has its own checked-out branch, its own index, and its own untracked files, but it shares the object store, refs, and configuration with the main checkout. For parallel coding agents this is the right isolation unit: each agent gets a directory nobody else writes to, its commits go on a branch nobody else has checked out, and creating the directory is a checkout rather than a clone or a container start. This article explains the commands, why worktrees beat a shared working directory, the failure modes you will meet, and how Ivy Tendril creates one worktree per plan and removes it after merge.

What a worktree is

Every git repository has one working directory by default. git worktree add attaches more. Each one is a full checkout that you can cd into, edit, build, and commit from.

# create a worktree one directory up, on a new branch
git worktree add ../feature-x -b feature-x

# list all worktrees for this repository
git worktree list
# /Users/dev/app             a1b2c3d [main]
# /Users/dev/feature-x       a1b2c3d [feature-x]

The new directory contains a .git file, not a .git directory. The file points back to the main repository's .git/worktrees/feature-x, which holds the index and HEAD for that worktree. Objects, refs, hooks, and config are read from the main repository. A commit made in ../feature-x is immediately visible from the main checkout with git log feature-x, with no fetch or push.

Two constraints follow from this design. A branch can be checked out in only one worktree at a time; git refuses to add a second worktree on the same branch. And the worktree directory should live outside the main working directory, otherwise the main checkout sees it as untracked files.

Why worktrees beat a shared working directory for agents

A coding agent edits files, runs commands, and commits. Two agents doing that in the same directory produce a single mixed diff, and neither agent's tests run against only its own changes. The alternatives are a separate clone per agent, a container per agent, or a worktree per agent.

Approach Own tree and branch Shared object store Startup cost Runtime isolation
Shared working directory No Yes None None
Clone per agent Yes No, full copy of objects Full clone, plus dependency install None
Container per agent Yes No, unless volume-mounted Image pull and container start Yes
Worktree per agent Yes Yes Checkout of one tree None

A worktree gives an agent what it needs for correctness (a private tree and a private branch) without what it does not need for most coding tasks (a private runtime). The object store is shared, so a repository with years of history costs one checkout of the current tree, not a copy of every object. Package manager caches keyed on lockfile hashes (pnpm, cargo, nuget) live in the user's home directory and are shared regardless.

Containers are still the right choice when agents install system packages or run services that bind ports. Worktrees and containers are not exclusive; a worktree can be mounted into a container. For the common case of edit, test, lint, commit, a worktree is enough.

Read agent orchestration patterns for where isolation sits among the other things an orchestrator has to own.

Failure modes and how to avoid them

Worktrees solve directory collisions. They do not solve three other problems, and each needs a rule.

Two agents editing the same files on different branches

Worktrees isolate directories, not intent. If two plans both modify auth/session.ts, both branches will apply cleanly on their own and the second one to merge will conflict. The place to catch this is before execution: when planning, look at which modules each plan touches and either sequence the plans or split them so that one plan owns each module.

Dirty trees

An agent that stops before finishing, or a test run that generates files, leaves a worktree with uncommitted changes. git worktree remove refuses to delete a dirty tree by default, which is correct, but it means an orchestrator has to decide what to do with the leftovers. The safe policy is to commit everything the agent produced onto its branch, so nothing is lost and the reviewer can see it, and only then remove the tree.

# inspect before removing
git -C ../feature-x status --short

# remove a clean worktree
git worktree remove ../feature-x

# force removal of a dirty one, after deciding the changes are not needed
git worktree remove --force ../feature-x

Forgotten worktrees

Worktrees created by hand accumulate. Each one holds a checked-out branch, which blocks anyone else from checking out that branch, and each one holds a full tree on disk. If a worktree directory is deleted with rm -rf instead of git worktree remove, git keeps a stale entry in .git/worktrees/ until it is pruned.

# see what would be pruned
git worktree prune --dry-run --verbose

# drop entries whose directories no longer exist
git worktree prune

The rule that prevents all three problems is the same: the thing that creates a worktree should be the thing that removes it, and it should do so at a defined point in the task's lifecycle.

How Ivy Tendril uses worktrees

Ivy Tendril is a local-first desktop application (macOS, Windows, Linux) that runs coding agents from plan to reviewed pull request. Worktrees are its execution unit. See the product overview and the lifecycle for the stage definitions.

  • One worktree per plan. When a plan moves from approved to executing, Tendril creates a worktree and a branch for it. Many plans execute at once, each in its own worktree, so the main branch receives no agent edits until review.
  • Verification runs inside the worktree. Tests, lint, and the diff are computed against that plan's tree alone. The Review app shows them as tabs, so the reviewer sees only the changes and results of the plan under review.
  • Cleanup after merge. When the pull request merges, Tendril removes the worktree. There is no manual prune step, and forgotten worktrees do not accumulate.
  • Agent-agnostic. The agent running inside the worktree can be Claude Code, OpenAI Codex CLI, GitHub Copilot CLI, Google Gemini CLI, OpenCode, or any other CLI agent, chosen per plan.
  • Local. The worktree, the plan, the agent's memory, and the execution logs stay on the machine. The only external calls are to the model API you configure and to GitHub. See local-first AI development.

Because every worktree is created by the orchestrator at a known stage and removed at a known stage, the failure modes above are handled by the workflow rather than by team discipline.

How to start

  1. Try it by hand first: git worktree add ../scratch -b scratch, run your agent inside ../scratch, and confirm your main checkout is untouched. Then git worktree remove ../scratch.
  2. Install Tendril: curl -sSf https://cdn.ivy.app/install-tendril.sh | sh (macOS, Linux) or irm https://cdn.ivy.app/install-tendril.ps1 | iex (Windows). Docs at installation.
  3. Create two plans that touch different modules, execute both, and run git worktree list in your repository while they run.

Tendril is free and source-available under the Functional Source License. Team features, on-prem hosting, SSO, and CI verification imports are on the Pro ($59 per user per month) and Enterprise plans.

Frequently asked questions

Does each worktree need its own node_modules or build output?

Yes. Worktrees share git objects but not untracked files, so each one has its own dependency directory and build output. Package managers with a global content-addressable store, pnpm for example, make the per-worktree install mostly hard links, so the disk and time cost is smaller than a fresh install.

Can two worktrees check out the same branch?

No. Git enforces one checkout per branch across all worktrees of a repository. For agent isolation this is useful: it makes it impossible for two agents to commit to the same branch at the same time.

What if the repository is very large?

The object store is shared, so adding a worktree costs one checkout of the current tree, not a copy of the history. If the tree itself is large, sparse checkout is configured per worktree, so each agent can check out only the directories its plan touches.

Written by

Ivy Team