ReadbackLesson 09In progress
4 steps · 30 minutes · one terminal

AGENTS INPARALLEL

Three agents, one repository. Branches alone are not enough — they share a single working tree, so two agents editing at once corrupt each other’s state. Worktrees give each one its own. And you can compute, before any of them finishes, exactly where they are going to collide.

What you already know

Retrieval · lessons 03 and 08

Two from memory. The first one is why branches alone do not solve this.

Answer before you move on

How many working trees and indexes does an ordinary git repository have?

Answer before you move on

Two branches both changed a file, in different places. Does merging them conflict?

One repository, several working trees

Claim + proof · git worktree add

The obvious way to run three agents on one project is three clones. It works, and it costs you three copies of the history, three sets of remotes to keep in sync, and no way to see one agent’s commits from another without pushing.

git worktree is the alternative: additional working trees, each with its own index and its own checked-out branch, all backed by one object database (git-worktree).

Executed, output verbatim
$ git worktree add -b agent-retry ../wt-retry
$ git worktree add -b agent-parse ../wt-parse
$ git worktree list
/tmp/l09/app       4e1d742 [main]
/tmp/l09/wt-parse  4e1d742 [agent-parse]
/tmp/l09/wt-retry  4e1d742 [agent-retry]

Three directories, three branches, one repository. The first line is the original clone; the other two are new directories beside it.

The mechanism is the plainest thing in this course. In a linked worktree, .git is not a directory — it is a file containing one line.

Executed, output verbatim
$ cat ../wt-retry/.git
gitdir: /tmp/l09/app/.git/worktrees/wt-retry

One line. A pointer back to the real repository, which is where every object lives — and the reason this is the only output in the course whose text depends on where you built it.

What is shared and what is not

The rule is one line of the docs: “all pseudo refs are per-worktree and all refs starting with refs/ are shared” (git-worktree, REFS). So shared: the object database, every branch, every tag, every remote-tracking ref — and the config file, which is “shared across all worktrees” by default. Not shared: the working tree, the index, and HEAD, which is a pseudo ref. Each agent therefore gets its own files and its own staging area, and every commit any of them makes is instantly an object all the others can see.

Predict before you read on

An agent working in wt-retry makes a commit. From wt-parse, with no fetch, no pull and no push, what does git log --oneline --all show?

Executed, output verbatim
$ git log --oneline --all
408cbae Retry five times
4e1d742 Add the app

Run from wt-parse, immediately after a commit made in wt-retry.

And git enforces the one rule that makes this safe: a branch can be checked out in at most one worktree. add “refuses to create a new worktree when <commit-ish> is a branch name and is already checked out by another worktree” (git-worktree), and switch refuses for the same reason. Two agents cannot end up on the same branch by accident — it takes --force to override, which is a thing you have to mean.

Executed, output verbatim
$ git switch agent-retry
fatal: 'agent-retry' is already used by worktree at '/tmp/l09/wt-retry'

A refusal, naming the directory that holds it. This is the collision that would be worst — two processes rewriting one branch — and it is impossible.

The stash is shared, and that one surprises people

refs/stash starts with refs/, so the rule above puts it on the shared side — one stash list for the whole repository, not one per worktree. Verified: git stash in wt-retry, then git stash list in wt-parse shows it, and git stash pop there would apply another agent’s work into your tree. Two agents that both stash are writing to the same stack. The exceptions to the rule are refs/bisect, refs/worktree and refs/rewritten, which are per-worktree despite the prefix. None of them come up here; the stash does.

What you still have to duplicate

Git shares its own data; it shares nothing else. Each worktree needs its own node_modules, its own build output, and its own .env — because those live in the working tree, and each worktree has a separate one. Untracked files do not travel between them either, which is usually what you want and occasionally a surprise.

If a second person joins the repo

Every guarantee on this page is a property of one repository, and a colleague is a different repository. The branch lock is the one that matters. It stops two of your worktrees from checking out one branch — but two clones can both sit on feature at the same time with no complaint from either, which is the ordinary state of any team. Verified: two clones of one repository, both switched to the same branch, no refusal. So the collision the lock makes impossible for your agents is merely normal between people, and what makes it survivable is that their commits arrive through a remote, where the push either fast-forwards or is refused. The same applies to the shared stash and the instant visibility of commits: both are consequences of one object database. Two people have two, so a colleague’s commit is invisible until somebody pushes and somebody fetches. When you scale from three agents to three people, the file-intersection screen still works — but it has to run on origin/* refs, after a fetch, rather than on local branches.

Set this up on a real project

git worktree add -b <branch> ../<dir> from any repository. git worktree list shows every one. git worktree remove ../<dir> cleans up, and git worktree prune tidies after a directory you deleted by hand.

2 of 4 steps remain

Compute the collision

You have read the first 2 steps in full — a claim and the verification that settles it. The rest of this lesson, and the 10 lessons after it, open when subscriptions do. Nothing that is free today will be taken away then.

Read the free reference
Subscriptions open soon
the free preview stays