Parallel Work Without Conflicts: Worktree Isolation for Agents
When several agents touch the same repo at once, they step on each other's changes. How git worktree isolation makes parallel work safe.
Start with the problem
The most common accident when running agents in parallel is conflict from sharing one working tree. While one agent edits files, another switches branches or overwrites the same file — and uncommitted work silently disappears. Because it vanishes without an error message, you usually discover it days later, asking "wait, where's the code I wrote yesterday?"
Picture a concrete scene. Agent A is refactoring the payments API. Uncommitted changes are piling up in the working directory. At that exact moment, Agent B runs git checkout main in the same repository to move to a different branch. As Git switches branches, it rewrites the files in the working directory to match the target branch. Any of A's unfinished, unstaged changes get overwritten, blocked by a conflict, or — in the worst case — wiped without a trace. A loses hours of work without ever knowing what went wrong.
The root of this accident is simple: a single working directory can hold exactly one branch and one file state at a time. But parallel agents each want a different branch and a different file state. It's like several people trying to redecorate one room to their own taste at the same time. Someone is guaranteed to trample someone else's work.
Why a shared working tree is dangerous
Peel back Git's structure and the reason becomes obvious. A single Git repository has three main layers.
- The object store (
.git) — the permanent history holding every commit, tree, and blob. A branch is ultimately just a pointer to a commit inside this store. - The index (staging area) — the staging space that gathers the changes destined for your next commit.
- The working directory (working tree) — the files actually laid out on the filesystem, the ones you edit directly.
The catch is that a traditional git clone repository has exactly one of each. HEAD points at one branch at a time; there is one index and one working directory. When two agents work in the same folder, they compete over these single resources. Commands like git stash, git checkout, and git reset can all silently overwrite this shared state.
A real case from our own history makes this vivid. In a shared checkout, several sessions manipulated git concurrently, and work that hadn't been committed yet got pushed aside by an external git operation and lost. Two lessons stuck: commit immediately at every step, and when you genuinely need isolation, use a worktree.
The fix: git worktree
git worktree lets one repository have multiple working directories, each checked out to a different branch. The key is that these worktrees share the object store (.git) while each keeps its own working directory, index, and HEAD. The history stays unified, but the file state you're editing right now is fully separated.
git worktree add ../agent-a feature/agent-a
git worktree add ../agent-b feature/agent-b
This creates two separate folders, ../agent-a and ../agent-b, existing side by side, each with its own branch checked out. Give each agent its own worktree, and they can work in parallel without stepping on each other's files. A can leave a file half-edited in feature/agent-a with zero effect on B's feature/agent-b folder. Each worktree has its own branch and file state, so A's unfinished changes are invisible to B.
Anatomy of an isolated workspace
Once you pin down exactly what a worktree shares versus what it keeps separate, the mechanics of isolation click into place. Each worktree has its own working directory, its own index, and its own HEAD. Meanwhile the object store — holding the commits, trees, and blobs — is a single thing everyone shares.
This design is clever because it captures isolation and efficiency at once. Because the working directories are separate, file edits never interfere. Yet because the history is unified, a commit made in one worktree is immediately visible from another. This is different from taking several git clone copies. A clone duplicates the entire object store, using several times the disk, and you need a fetch to see each other's commits. Worktrees share the store, so they save disk and share commits instantly.
When to isolate
Isolation isn't free. Creating a worktree lays out another copy of the file tree on disk, and you may have to redo dependency installs (like npm ci) or environment setup per worktree. So the rule isn't "always isolate" — it's isolate when interference is actually possible.
- When two agents might touch the same file or module. Editing overlapping code simultaneously makes conflict only a matter of time.
- When trialing a risky refactor apart from the main line. Sweeping rewrites are safer in a separate space you can always throw away.
- When a failure must not pollute the main workspace. Even if the experiment goes wrong, you just discard the isolated folder and you're back to a clean state.
- When an agent switches branches often or heavily manipulates staging. In a shared tree, that easily tramples the agent next door.
Conversely, if agents only touch different files, isolation can be overkill — it carries a disk and setup cost. If one agent only edits docs and another only edits a completely separate service folder, you often don't need to split worktrees at all; the discipline of committing often is enough.
The practical workflow
In practice it flows like this. First create a worktree per agent, and let each work from its own folder.
# One isolated worktree per agent
git worktree add ../agent-a feature/agent-a
git worktree add ../agent-b feature/agent-b
# Commit often in each worktree — the first line of defense against loss
cd ../agent-a && git add -A && git commit -m "wip: API draft"
# List the current worktrees
git worktree list
The single most important discipline here is committing often. Only uncommitted changes are exposed to the risk of loss. Once committed, a change is safely recorded in the object store, and even if you delete a worktree by mistake, you can recover as long as the branch survives. That's why "commit immediately at every step" is the fundamental of parallel work.
When you merge
Commit often in each worktree, and integrate finished work via a PR. This is where branches that fanned out in parallel come back together into a single main after review. A human inspects the changes here and resolves any conflicts. Once integration is done, clean up worktrees that weren't changed to cut down on disk and clutter.
# Remove a worktree you no longer need after integration
git worktree remove ../agent-a
# Tidy up tangled references
git worktree prune
Common pitfalls
As you work with worktrees you'll hit a few snags. Knowing them in advance avoids most of them.
- Two worktrees can't check out the same branch at once. Git blocks it. This isn't a bug, it's a safeguard — pushing one branch from two places would tangle the history. Give each agent a different branch.
- Dependencies and environment don't come along automatically. A new worktree shares source but not gitignored artifacts like
node_modules. You may neednpm cior a build right after creating one. - Uncommitted changes are still vulnerable. Worktree isolation only guarantees "different folders"; it doesn't stop you from accidentally reverting uncommitted changes within one folder. The habit of committing often is the last line of defense.
- Forget to clean up and worktrees pile up. Remove finished worktrees with
git worktree remove, and tidy tangled references withgit worktree prune.
In Marblo
Marblo can spawn an agent in an isolated worktree when needed, so parallel work doesn't collide. For tasks where several agents risk touching the same file or module, the orchestrator assigns each agent its own worktree. Each agent edits files freely in its own folder on its own branch, untouched by the neighbor's unfinished changes.
When the work is done, results flow out as commits and a PR, and a human inspects them at the REVIEW stage. And because a worktree with no changes is cleaned up automatically, even an experiment that leads nowhere leaves no residue in your workspace. Pushing forward in parallel while keeping each task safely separated — this is how Marblo actually realizes "controllable parallelism."
Controllable parallelism — isolation is its foundation. The power to run an agent fleet at once is only safely unleashed on top of the guarantee that they won't step on each other. git worktree provides that guarantee at the repository level, and Marblo folds it naturally into the orchestration flow. If you want the wider picture, What Is Marblo continues into how the orchestrator, kanban board, and heterogeneous agents fit together.
Comments
Comments are coming soon.