Skip to content
Gespräch vereinbaren
AI Engineering

Claude Code Worktrees: paralleles Arbeiten mit `--worktree` richtig aufsetzen

Felix Schmidt

Du arbeitest mit Claude Code an einem neuen Feature. Der Plan steht, der halbe Flow ist fertig, Claude hat den Kontext im Kopf. Dann kommt ein dringender Produktions-Bug dazwischen.

Also öffnest du ein zweites Terminal und startest dort claude — im selben Projektverzeichnis. Jetzt laufen zwei Sessions auf demselben Checkout: die eine baut das Feature, die andere fixt den Bug. Früher oder später schreiben sie sich gegenseitig dieselben Dateien um. Am Ende sind beide Stände vermischt, und der Kontext der ersten Session ist hin.

Genau dieses Problem lösen Worktrees. Seit dem nativen CLI-Support (eingeführt im Februar 20261) muss man dafür nichts mehr von Hand verdrahten — ein Flag genügt.

Was ein Worktree eigentlich ist

Ein Git-Worktree ist laut Anthropic-Doku "a separate working directory with its own files and branch"2 — also ein zusätzliches Arbeitsverzeichnis mit eigenem Branch, das sich dieselbe .git-Historie und dieselben Remotes mit deinem Haupt-Checkout teilt. Du klonst also nicht das ganze Repo neu; du bekommst nur eine zweite, isolierte Arbeitskopie. Edits in der einen Kopie berühren die Dateien der anderen nicht. Das ist der entscheidende Punkt: zwei Claude-Sessions können parallel laufen, ohne sich gegenseitig die Dateien umzuschreiben.

Quickstart

Das Flag --worktree (Kurzform -w) erzeugt den Worktree und startet Claude direkt darin:

claude --worktree feature-checkout

Standardmässig landet der Worktree unter .claude/worktrees/<name>/ im Repo-Root, auf einem neuen Branch namens worktree-<name> — im Beispiel also .claude/worktrees/feature-checkout/ auf worktree-feature-checkout.2

Drei Dinge, die man am Anfang wissen sollte:

  • Namen weglassen: claude --worktree ohne Argument generiert einen Zufallsnamen wie bright-running-fox.2
  • .gitignore ergänzen: Trage .claude/worktrees/ in deine .gitignore ein, sonst tauchen die Worktree-Inhalte im Haupt-Checkout als untracked files auf.2
  • Trust-Dialog: Bevor --worktree in einem Verzeichnis das erste Mal interaktiv funktioniert, musst du dort einmal claude starten und den Workspace-Trust bestätigen. Sonst bricht --worktree mit einer Fehlermeldung ab. Nicht-interaktive Läufe mit -p überspringen den Trust-Check.2

Der Praxis-Fall: zwei Spuren parallel

Zurück zur Ausgangssituation. So sieht der saubere Ablauf aus. Terminal 1 bleibt auf dem Feature:

# Terminal 1 — Feature
claude --worktree feature-checkout

Terminal 2 bekommt eine eigene, isolierte Spur für den Hotfix:

# Terminal 2 — Hotfix
claude --worktree fix-cart-total

Danach sieht das Repo so aus:

shop-web/
├── .claude/worktrees/
│   ├── feature-checkout/   # Branch: worktree-feature-checkout
│   └── fix-cart-total/     # Branch: worktree-fix-cart-total
└── src/                    # dein Haupt-Checkout, unangetastet

Beide Sessions laufen gleichzeitig, jede mit eigenem Dateistand und eigenem Branch. Der Bugfix landet sauber auf worktree-fix-cart-total, das Feature wächst ungestört auf worktree-feature-checkout weiter. Kein Stash, kein Branch-Wechsel, kein verlorener Kontext.

Von welchem Branch wird abgezweigt? Per Default branchen Worktrees von origin/HEAD, also vom Default-Branch des Remotes — du startest damit von einem sauberen Stand, der dem Remote entspricht. Ist kein Remote konfiguriert oder schlägt der Fetch fehl, fällt Claude auf deinen lokalen HEAD zurück.2 Willst du stattdessen immer vom lokalen HEAD abzweigen (inklusive deiner noch nicht gepushten Commits), setzt du in den Settings:

{
  "worktree": {
    "baseRef": "head"
  }
}

Das Setting akzeptiert ausschliesslich "fresh" oder "head", keine beliebigen Git-Refs.2 "head" ist vor allem dann nützlich, wenn isolierte Subagents auf laufender, nicht gepushter Arbeit operieren sollen.

Aus einem PR heraus arbeiten: Übergibst du eine PR-Nummer mit #, holt Claude pull/<nummer>/head von origin und legt den Worktree unter .claude/worktrees/pr-<nummer> an:2

claude --worktree "#1234"

Gitignorte Dateien mitnehmen: .worktreeinclude

Ein Worktree ist ein frischer Checkout. Heisst: Untracked files wie .env oder .env.local sind dort nicht vorhanden — und ohne die startet die Webapp im Worktree schlicht nicht. Dafür gibt es .worktreeinclude im Projekt-Root. Die Datei nutzt .gitignore-Syntax, und kopiert werden nur Dateien, die sowohl auf ein Muster passen als auch gitignored sind. Getrackte Dateien werden nie dupliziert.2

# .worktreeinclude
.env
.env.local
config/secrets.json

Das greift bei --worktree, bei Subagent-Worktrees und bei den parallelen Sessions der Desktop-App.2

Subagents isolieren

Worktrees sind nicht nur für ganze Sessions da. Auch Subagents können in eigenen Worktrees laufen, damit parallele Edits nicht kollidieren. Zwei Wege:

  • Ad hoc: Claude bitten, "use worktrees for your agents".
  • Dauerhaft: im Frontmatter eines Custom-Subagents isolation: worktree setzen.2

Jeder Subagent bekommt dann einen temporären Worktree, der automatisch wieder entfernt wird, wenn der Subagent ohne Änderungen fertig wird. Die Base-Branch-Logik ist dieselbe wie bei --worktree.2

Mitten in der Session umschalten

Du musst dich nicht beim Start entscheiden. Sagst du Claude mitten in einer Session "work in a worktree", legt es über das EnterWorktree-Tool einen an und verschiebt die Session hinein — praktisch, wenn du erst auf halber Strecke merkst, dass deine Änderungen Isolation brauchen. Aus einem Worktree heraus kann Claude per EnterWorktree direkt zu einem anderen unter .claude/worktrees/ wechseln; der vorherige bleibt unangetastet auf der Platte liegen.2

Aufräumen

Was beim Verlassen einer Worktree-Session passiert, hängt davon ab, ob es Änderungen gab:2

  • Nichts uncommitted, keine untracked files, keine neuen Commits: Worktree und Branch werden automatisch entfernt. Hat die Session einen Namen, fragt Claude stattdessen nach — du kannst den Worktree für später behalten.
  • Uncommitted changes, untracked files oder neue Commits: Claude fragt nach behalten oder entfernen. Entfernen löscht Verzeichnis und Branch — inklusive aller nicht committeten Änderungen.
  • Nicht-interaktive -p-Läufe: Worktrees aus --worktree werden hier nicht automatisch aufgeräumt (es gibt keinen Exit-Prompt). Manuell entfernen mit git worktree remove.

Worktrees, die Claude für Subagents oder Background-Sessions angelegt hat, werden automatisch entfernt, sobald sie älter als dein cleanupPeriodDays-Setting sind — vorausgesetzt, sie sind sauber. Worktrees aus --worktree fasst dieser Sweep nie an.2 Während ein Agent läuft, sperrt Claude dessen Worktree per git worktree lock, damit eine parallele Aufräum-Aktion ihn nicht wegräumt.2

Was keiner sagt: Datei-Isolation ist nicht Runtime-Isolation

Hier wird es ehrlich. Für eine Library oder ein CLI-Tool ist --worktree allein die ganze Geschichte: Quellcode rein, isoliert bauen, fertig. Für eine echte Webapp nicht.

Worktrees isolieren Dateien, nicht den Laufzeit-Zustand. Zwei typische Stolpersteine, die in keinem Marketing-Snippet stehen:34

  • Port-Konflikt: Dein Dev-Server läuft auf Port 3030. Der zweite Worktree will denselben Port. Ohne Eingriff startet die zweite Instanz nicht.
  • Geteilte Datenbank: Beide Worktrees zeigen auf dieselbe Postgres-Instanz. Agent A fährt eine Migration — und Agent B sitzt plötzlich auf einem inkonsistenten Schema.

Die Datei-Isolation ist also notwendig, aber nicht hinreichend. Der saubere Fix führt über einen WorktreeCreate-Hook, der die gesamte Worktree-Erzeugung ersetzt: Er liest den Worktree-Namen von stdin, legt das Verzeichnis an, schreibt eine .env.local mit einem aus dem Branch-Namen abgeleiteten, eindeutigen DB-Namen und Port, ruft dein Setup-Skript auf und gibt den Pfad auf stdout zurück — diesen Pfad nutzt Claude dann als Working Directory.3 Ein passender WorktreeRemove-Hook räumt am Ende DB und Verzeichnis wieder ab. Genau dieser Hook-Mechanismus ist auch der offizielle Weg für Nicht-Git-VCS (SVN, Perforce, Mercurial); weil der Hook die Default-Logik ersetzt, wird .worktreeinclude dann nicht mehr verarbeitet.2

Konkrete Empfehlungen nach Stack

Library / CLI-Tool (kein Runtime-State). Hier reicht --worktree allein. Einmalig die Worktree-Verzeichnisse aus dem Haupt-Checkout heraushalten:

echo ".claude/worktrees/" >> .gitignore

Danach startest du parallele Sessions einfach mit claude --worktree <name>. Kein Hook, keine weitere Konfiguration.

Full-Stack-Webapp (Node/TypeScript + Postgres). Datei-Isolation allein genügt nicht — du brauchst pro Worktree eine eigene DB und einen eigenen Port. Zwei Ausbaustufen:

Stufe 1 — nur Config mitnehmen. Wenn deine parallelen Agents nicht gleichzeitig dieselbe DB beschreiben, reicht oft .worktreeinclude, um die .env-Dateien in jeden Worktree zu kopieren:

# .worktreeinclude
.env
.env.local

Stufe 2 — echte Runtime-Isolation per Hook. Sobald Agents wirklich gleichzeitig laufen, brauchst du eindeutige DB-Namen und Ports. Das übernimmt ein WorktreeCreate-Hook. Wichtig zu verstehen: Sobald dieser Hook existiert, ersetzt er die komplette Default-Logik — git worktree add rufst du dann selbst im Skript auf, und .worktreeinclude wird nicht mehr verarbeitet (du kopierst die Config stattdessen im Hook).2

Erst die Settings, die auf zwei Skripte zeigen:

// .claude/settings.json
{
  "hooks": {
    "WorktreeCreate": [
      { "hooks": [{ "type": "command", "command": "bash .claude/hooks/worktree-create.sh" }] }
    ],
    "WorktreeRemove": [
      { "hooks": [{ "type": "command", "command": "bash .claude/hooks/worktree-remove.sh" }] }
    ]
  }
}

Dann das Erzeugungs-Skript. Es liest den Worktree-Namen von stdin, legt den Worktree an, kopiert die Config, leitet DB-Name und Port aus dem Branch-Namen ab und gibt am Ende den Pfad auf stdout zurück — diesen Pfad nutzt Claude Code als Working Directory:23

#!/usr/bin/env bash
# .claude/hooks/worktree-create.sh
set -euo pipefail

NAME=$(jq -r .name)                 # Worktree-Name kommt als JSON ueber stdin
DIR=".claude/worktrees/$NAME"
DB="shop_${NAME//-/_}"
PORT=$(( 3030 + $(echo -n "$NAME" | cksum | cut -d' ' -f1) % 1000 ))

git worktree add -b "worktree-$NAME" "$DIR" origin/HEAD >&2   # Worktree selbst anlegen
cp .env "$DIR/.env" 2>/dev/null || true                      # gitignorte Config mitnehmen
createdb "$DB" >&2                                            # eigene DB pro Branch

cat > "$DIR/.env.local" <<EOF                                 # eindeutige DB + Port hineinschreiben
DATABASE_URL=postgres://localhost/$DB
PORT=$PORT
EOF

( cd "$DIR" && npm install && npm run db:migrate ) >&2        # Setup im Worktree

echo "$DIR"                                                  # Pfad = Vertrag mit Claude Code

Und der Gegenpart zum Aufräumen, der DB und Verzeichnis wieder abbaut:

#!/usr/bin/env bash
# .claude/hooks/worktree-remove.sh
set -euo pipefail

NAME=$(jq -r .name)
dropdb --if-exists "shop_${NAME//-/_}" >&2
git worktree remove --force ".claude/worktrees/$NAME" >&2

Das exakte stdin-Schema steht im Hooks-Referenzdokument; die Felder können je nach Version leicht abweichen.2

Subagent-lastige Workflows. Ein Custom-Subagent ist eine Markdown-Datei unter .claude/agents/<name>.md. Der Block zwischen den beiden ----Zeilen am Dateianfang ist das Frontmatter — die YAML-Konfiguration des Agents; darunter steht sein System-Prompt. Trägst du dort die Zeile isolation: worktree ein, bekommt dieser Agent bei jedem Lauf automatisch seinen eigenen Worktree — du musst es nicht mehr bei jedem Aufruf ansagen. Beispiel für einen Test-Runner, der Destruktives tun kann und deshalb isoliert laufen soll:

---
name: test-runner
description: Fuehrt die Test-Suite aus und meldet Fehlschlaege zurueck
tools: Read, Bash, Glob, Grep
model: sonnet
isolation: worktree
---
Du bist ein Test-Runner. Wenn du aufgerufen wirst, fuehre die komplette
Test-Suite aus, fasse Fehlschlaege zusammen und gib nur das Ergebnis zurueck.

Die Datei legst du selbst an (oder über den /agents-Befehl). name und description sind Pflicht; isolation: worktree ist die eine Zeile, die den Agent in einen eigenen Worktree zwingt.2

Desktop-App. Hier brauchst du nichts davon: im Code-Tab den Worktree-Modus aktivieren, und jede neue Session bekommt automatisch einen eigenen Worktree. Speicherort und Branch-Präfix lassen sich in den Settings anpassen. Der bequemste Weg, wenn du nicht im Terminal hantieren willst.2

Wann nicht. Bei sequenziellen, voneinander abhängigen Aufgaben (Feature B baut auf Feature A auf) bringen parallele Worktrees nichts. Und für einen Einzeiler-Fix lohnt der Overhead nicht.

Das Muster dahinter ist simpel: Du wirst vom Coder zum Koordinator. Jeder Worktree ist eine eigene Spur, jede Spur ein eigener Branch, jeder Branch ein eigener, sauber reviewbarer Change. Die Kunst liegt nicht im Flag — die liegt darin, die Runtime-Isolation nachzuziehen, die das Flag dir nicht schenkt.

FAQ

Kann man das Modell innerhalb eines Worktrees wechseln?

Ja. Ein Worktree ist nur Verzeichnis plus Branch — die Session darin ist eine ganz normale Claude-Code-Session. Das Modell wechselst du mitten drin mit /model oder startest gleich mit claude --worktree <name> --model <modell>. Der Worktree bindet dich an kein Modell. Nutzt du isolierte Subagents, kann jeder Subagent im Frontmatter sein eigenes Modell festlegen (model: ...), unabhängig von der Hauptsession.

Können in einem Worktree mehrere Sessions existieren?

Hier hilft die Trennung von Zeitachse und Gleichzeitigkeit. Nacheinander problemlos: Du kannst im selben Worktree-Verzeichnis mehrere Sessions starten, eine fortsetzen oder benennen — über die Lebensdauer eines Worktrees können also mehrere Sessions zu ihm gehören. Gleichzeitig ist es technisch möglich (zwei Terminals im selben Verzeichnis), baut aber genau die Datei-Kollisionen wieder auf, die Worktrees verhindern sollen. Das Designprinzip lautet daher: genau eine gleichzeitige Session pro Worktree, und für echte Parallelität bekommt jede Session ihren eigenen Worktree — so macht es auch die Desktop-App automatisch. Die saubere Ausnahme sind Subagents mit isolation: worktree: die laufen gerade nicht im selben, sondern jeweils in ihrem eigenen Worktree.


Footnotes

  1. Verdent Guides, "Claude Code Worktree Kurulum Rehberi" — verweist auf nativen --worktree-Support ab Claude Code v2.1.49 (19.02.2026). https://www.verdent.ai/guides/claude-code-worktree-setup-guide (abgerufen am 15.06.2026)

  2. Anthropic, "Run parallel sessions with worktrees", Claude Code Docs. https://code.claude.com/docs/en/worktrees (abgerufen am 15.06.2026) 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

  3. D. Galarza, "Extending Claude Code Worktrees for True Database Isolation". https://www.damiangalarza.com/posts/2026-03-10-extending-claude-code-worktrees-for-true-database-isolation/ (abgerufen am 15.06.2026) 2 3

  4. Trigger.dev, "We ditched worktrees for Claude Code. Here's what we use instead". https://trigger.dev/blog/parallel-agents-gitbutler (abgerufen am 15.06.2026)

Dieses Thema betrifft dein Team? Lass uns besprechen, wie ich helfen kann.

Diese Website verwendet Drittdienste (Google reCAPTCHA, Calendly), die Cookies setzen können. Mehr dazu in meiner Datenschutzerklärung .