Open drie terminals, typ in alle drie claude --worktree, en tien seconden later werken er drie agents aan drie features in drie mappen. Niets overlapt. Niets botst.
Dat is de belofte, en voor je bestanden klopt hij.
De rest van je machine blijft gedeeld, en juist dat gedeelde stuk kan je lelijk opbreken.
Wat een git worktree echt afschermt
Een git worktree is een tweede werkmap met eigen uitgecheckte bestanden, een eigen index en een eigen branch, die naar dezelfde repository wijst. Eén clone, meerdere werkmappen. Meer is het niet.
Claude Code heeft er first-class support voor. Geef --worktree (of -w) een naam mee en je krijgt een map in .claude/worktrees/<naam>/ op een nieuwe branch die worktree-<naam> heet:
claude --worktree feature-authLaat je de naam weg, dan verzint hij er een, zoiets als bright-running-fox. Met --tmux komt de sessie in een eigen tmux-venster terecht. Geef in plaats van een naam een pull request mee en hij haalt pull/<nummer>/head voor je op:
claude --worktree "#1234"Zet er quotes omheen, anders ziet je shell alles na de # als commentaar.
Subagents kunnen hetzelfde krijgen. Zet isolation: worktree in de frontmatter van een eigen subagent en elke run draait in een wegwerp-checkout:
---
name: refactorer
description: Applies mechanical refactors across many files
isolation: worktree
---Zolang die agent draait, zet Claude Code er met git worktree lock een slot op, zodat de periodieke opruimactie de map niet onder hem vandaan haalt.
Zet .claude/worktrees/ in je .gitignore voordat je begint, anders loopt je hoofdcheckout vol met untracked bestanden van andere agents.
De base branch is niet waar jij staat
Hier lopen de meeste mensen op stuk. Nieuwe worktrees branchen niet van je huidige HEAD, maar van de default branch van je repository op de remote.
Dat is de instelling worktree.baseRef en die staat standaard op "fresh". Je zit vier commits diep op een feature-branch, je start een worktree om een agent iets kleins ernaast te laten oplossen, en die agent begint ongemerkt vanaf origin/main. Alles wat je nog niet gepusht hebt, is er gewoon niet.
Voor een taak die er echt los van staat, is dat precies goed. Voor het gewone geval, waarbij het parallelle werk voortbouwt op waar je mee bezig bent, moet je dat aangeven:
{
"worktree": {
"baseRef": "head"
}
}Binnen een worktree wijst "head" naar de HEAD van die worktree zelf, niet naar die van je hoofdcheckout.
Een verse checkout is nog geen werkomgeving
Een worktree checkt getrackte bestanden uit. Alleen getrackte bestanden.
Dus je .env staat er niet. Je .env.local staat er niet. Je node_modules staat er niet.
Voor de env-kant is er een oplossing van Claude Code zelf: een bestand .worktreeinclude in de root van je project, met gitignore-syntax. Alles wat op een patroon matcht én gitignored is, wordt gekopieerd naar elke worktree die Claude aanmaakt.
.env
.env.local
config/secrets.jsonJe dependencies zijn je eigen probleem. Elke worktree heeft een eigen install nodig voordat een agent iets kan bouwen of testen, en er zijn mensen die in één middag tien gigabyte kwijt waren aan automatisch aangemaakte worktrees.
Met npm is dat gewoon de prijs die je betaalt. De content-addressable store van pnpm symlinkt packages vanaf één plek op schijf, waardoor de tweede install bijna niets kost. Dit is dat zeldzame moment waarop de discussie over je package manager ophoudt een geloofskwestie te zijn en gewoon rekenwerk wordt.
Poorten en databases waren nooit afgeschermd
Een worktree geeft elke agent eigen bestanden. Alles wat daaromheen draait, blijft gedeeld.
Twee agents die npm run dev draaien, vechten om poort 3000. Ze delen ook je lokale Postgres, je Docker-daemon, je Redis, je build-caches en elke artifact-map buiten de repository. Agent A draait een migratie, de tests van agent B beginnen te falen, en geen van tweeën kan achterhalen waarom.
Daar helpen worktrees niet bij, want git heeft geen mening over je dev-server. Geef elke worktree een eigen poort in zijn .env.local en een eigen databasenaam, of accepteer dat er maar één agent tegelijk de hele stack mag draaien.
Wil je isolatie op runtime-niveau, dan heb je containers nodig. Een worktree is de git-laag. Een container is de proceslaag. Ze vullen elkaar aan, en de een vervangt de ander niet.
Die ene .git waar ze allemaal in schrijven
Elke worktree deelt de .git-map van de repository. Dat delen is bewust zo ontworpen, en precies daarom zijn worktrees goedkoop genoeg om er per taak een aan te maken.
Het maakt je refs ook globaal.
- Stashes worden gedeeld. De stash-lijst staat in
.git. Een agent die in één worktree stasht, zet die stash in de lijst van elke sessie, waar hij in de verkeerde werkmap gepopt kan worden. - Branches worden gedeeld. Verwijder een branch in één worktree en hij is overal weg. Dezelfde branch twee keer uitchecken kan niet, en dat is de enige botsing die git echt voor je afvangt.
- Force-operaties worden gedeeld. Een
reset --hardof een rebase op een branch waar een andere worktree op staat, richt precies evenveel schade aan als zonder worktrees.
Lees dat rijtje terug en je ziet dat het de destructieve helft van git is. Worktree-isolatie beschermt je bestanden tegen een agent die in de war is, en doet niets aan de commando's die je geschiedenis herschrijven. Zou je een agent in je hoofdcheckout geen git push --force geven, dan moeten je permissieregels dat binnen een worktree net zo goed zeggen.
De afscherming werkt maar één kant op
Dat punt over permissies heeft een vervelende keerzijde.
Keur je in een worktree-sessie een Bash-commando goed met "Ja, niet meer vragen", dan komt die regel terecht in de .claude/settings.local.json van je hoofdcheckout. Hij geldt daar, hij geldt in elke andere worktree, en hij overleeft de worktree waarin je hem hebt goedgekeurd.
Dat is ook het juiste gedrag. Niemand wil npm test in vijf wegwerpmappen opnieuw goedkeuren. Besef alleen wél wat dat betekent: bestanden gaan naar binnen en blijven daar, permissies gaan naar buiten en blijven plakken.
De wegwerpomgeving schrijft in je vaste configuratie. Een antwoord dat je om twee uur 's nachts geeft in een map die je zo weggooit, geldt daarna gewoon overal.
Opruimen moet een gewoonte worden
Sluit je een interactieve worktree-sessie af, dan kijkt Claude of er gewijzigde bestanden, untracked bestanden of nieuwe commits in staan. Is de worktree schoon en had hij geen naam, dan verdwijnen de map en de branch vanzelf. In alle andere gevallen vraagt hij of je hem wilt houden of weggooien.
Twee gevallen waarin dat niet gebeurt:
- Runs met
-phebben geen afsluitvraag, dus headless sessies ruimen nooit achter zich op. Die haal je zelf weg metgit worktree remove. - Subagent-worktrees waar nog werk in zit blijven staan totdat een periodieke opruimactie ze kan weghalen zonder iets kwijt te raken. Dat gaat via de instelling
cleanupPeriodDays.
Draai af en toe git worktree list. Zodra je agents gaat scripten, loopt je schijf al vol voordat git ook maar begint te klagen.
Genereren schaalt parallel, reviewen niet
Alles hierboven los je op met een ochtendje inrichten. Het echte plafond ligt ergens anders.
Wie dit serieus doet, komt uit op drie tot vijf agents tegelijk. De tooling kan er prima acht aan. Jij niet. Vijf worktrees leveren vijf branches op die allemaal gelezen moeten worden, en lezen is het stuk dat nooit sneller is geworden.
Teams die verder komen halen de overlap weg in plaats van er isolatie bij te zetten: één bestand, één eigenaar, geen twee lopende taken die dezelfde code aanraken. Zo sluit je conflicten bij voorbaat uit in plaats van ze achteraf op te lossen, en het dwingt je om na te denken voordat er ook maar één agent start. Daar hoorde dat denkwerk sowieso al thuis.
Snelheid werd goedkoop, oordeel niet, en parallelle agents zijn daar de zuiverste vorm van. Genereren vermenigvuldig je met één shell-flag. Hoeveel jij begrijpt van wat er terugkomt, is nog precies hetzelfde als gisteren.
Eén taak, één worktree, opgeruimd als het klaar is
Dat is dezelfde regel als clearen op de grens tussen twee taken, alleen toegepast op je bestandssysteem in plaats van op je context window. Een lange sessie verzamelt verouderde context. Een worktree die te lang blijft staan verzamelt een verouderde omgeving: een branch die ergens vorige week van main is afgedreven, dependencies van twee lockfiles geleden, een database die halverwege een migratie is blijven hangen.
Isolatie is een reeks keuzes over bestanden, refs, poorten, data en permissies, en --worktree maakt er precies één van voor je.
Zorg dat de andere vier bewuste keuzes zijn.