Automatische Worktree-Löschung durch Claude Code mit git worktree lock verhindern
Dieser Artikel analysiert die interne Bereinigungslogik von Claude Code (v2.1.263) für mit `--worktree` erstellte Worktrees. Wenn eine Sitzung ohne ausstehende Änderungen und ohne neue Commits endet, werden der Worktree und sein Zweig stillschweigend gelöscht. Durch die Untersuchung des gebündelten Quellcodes werden die genauen Bedingungen für diese Löschung aufgedeckt und erklärt, wie Claude Code `git worktree lock` mit einem bestimmten Grundformat zur Verfolgung seiner Sitzungen verwendet. Jede Sperre mit einem Grund, der nicht dem Muster entspricht, wird als externe Sperre betrachtet und somit vor der Bereinigung geschützt. Praktische Lösungen umfassen manuelles Entsperren und erneutes Sperren oder die Automatisierung über einen `SessionStart`-Hook.
Hintergrund und Problemstellung
Claude Code bietet mit dem `--worktree`-Modus die Möglichkeit, Sitzungen in isolierten Git-Worktrees auszuführen, ohne das Hauptverzeichnis zu beeinträchtigen. Doch nach einer scheinbar harmlosen Sitzung – etwa Code-Recherche oder experimentelle Änderungen, die rückgängig gemacht wurden – und anschließendem `/exit` verschwinden der Worktree und der zugehörige Branch lautlos. Viele Entwickler gehen fälschlich davon aus, dass ein „sauberer“ Zustand den Worktree erhält, und verlieren so den gesamten erarbeiteten Kontext.
Die offizielle Dokumentation klassifiziert dieses Verhalten als Designmerkmal: Wenn weder uncommittete Änderungen noch neue Commits vorliegen und die Sitzung nicht benannt wurde, erfolgt eine stille Löschung. Bei benannten Sitzungen erscheint ein „Keep/Remove“-Dialog. Ein globaler Schalter, um dieses Verhalten dauerhaft zu deaktivieren, existiert nicht. In den Issue-Trackern (z. B. #27753, #46444, #58432) häufen sich Meldungen betroffener Nutzer, die jedoch stets mit „working as intended“ geschlossen werden. Dies verdeutlicht die Diskrepanz zwischen der automatischen Bereinigung und den tatsächlichen Anforderungen in der Praxis – insbesondere für reine Recherche-Szenarien ohne Git-Spuren.
Architektur und Mechanismus
Die Bereinigungslogik liegt im gebündelten JavaScript von Claude Code und lässt sich durch Reverse Engineering nachvollziehen. Beim Aufruf von `/exit` prüft Claude Code zwei Git-Statusindikatoren: Zunächst `git status --porcelain` auf ungestufte Änderungen oder ungetrackte Dateien, anschließend `git rev-list --count <session-start-HEAD>..HEAD` auf die Anzahl neuer Commits seit Sitzungsbeginn. Aus der Kombination ergeben sich drei Verhaltensklassen: Beide Null und Sitzung unbenannt → stille Löschung; beide Null und Sitzung benannt → Dialog; mindestens einer ungleich Null → Dialog (unabhängig von Benennung).
Die kritische Masche ist der erste Fall: null Änderungen, null Commits, unbenannte Sitzung – exakt das Szenario, in dem ein Entwickler nach einer Recherche ohne bleibende Git-Spuren dennoch den Kontext erhalten möchte. Interessanterweise verwendet Claude Code selbst `git worktree lock`, um Sitzungslocks zu verwalten. Beim Start wird ein Lock mit einem festen Format gesetzt: `claude session <name> (pid <PID> start <timestamp>)`. Beim Beenden prüft ein regulärer Ausdruck `/^claude (?:agent|session) .{1,255} \( pid (\d{1,10})(?: start (.{1,255}))? \)$/`, ob der Lock von der aktuellen Sitzung stammt. Ist die Lock-Ursache nicht kompatibel (etwa durch eine benutzerdefinierte Zeichenkette), wird angenommen, der Worktree sei durch einen anderen Prozess gesperrt, und die Bereinigung unterbleibt. Git selbst garantiert: „sweep“ entfernt niemals einen von Ihnen selbst gesetzten Lock.
Ein praktischer Schutz nutzt diesen Mechanismus. Während die Sitzung läuft, kann in einem zweiten Terminal (oder über den `!`-Befehl innerhalb von Claude Code) zuerst `git worktree unlock .claude/worktrees/<name>` ausgeführt werden, um Claude Codes eigenen Lock aufzuheben, und anschließend `git worktree lock --reason "pinned by developer" .claude/worktrees/<name>`, um einen neuen Lock mit eigener Ursache zu setzen. Die Reihenfolge ist wichtig: Ein `lock` auf einen bereits existierenden Lock schlägt fehl. Nach dem Ersetzen erkennt Claude Code beim Beenden, dass die Lock-Ursache nicht zum erwarteten Muster passt, und überspringt die Löschung. Der Worktree bleibt bestehen und kann mit `claude --worktree wt-lock` erneut genutzt werden.
Benchmarks und praktischer Nutzen
In einem Test-Repository lässt sich das Phänomen reproduzieren: `claude --worktree wt-clean` startet eine Sitzung in einem leeren Worktree; sofortiges `/exit` führt zu einer flüchtigen Meldung `Cleaning up worktree (no pending changes)…` – der Worktree und der Branch sind verschwunden. `git worktree list` zeigt nur noch den Haupt-Worktree. Der gesamte Vorgang dauert unter einer Sekunde und bietet kein Zeitfenster zum Eingreifen.
Die beschriebene Lock-Ersatzmethode funktioniert zuverlässig. Nach dem Setzen des benutzerdefinierten Locks erscheint der Worktree in `git worktree list` als `locked`. Ein erneutes `claude --worktree wt-lock` kann ihn ohne Einschränkung verwenden. Für Automatisierung bietet sich ein `SessionStart`-Hook im Verzeichnis `.claude/hooks/` an. Ein Skript `pin-worktree.sh` kann mittels `git rev-parse --git-dir` und `--git-common-dir` prüfen, ob es sich um einen Linked Worktree (nicht den Haupt-Worktree) handelt, und dann die `unlock`+`lock`-Sequenz ausführen. So wird jeder neue Worktree automatisch geschützt, ohne manuelles Eingreifen.
Der engineeringtechnische Wert liegt auf der Hand: Die Lösung ist vollständig in die vorhandene Git-Infrastruktur eingebettet, benötigt keine Modifikation von Claude Code und lässt sich mit einem einfachen Shell-Script umsetzen. Sie skaliert auf Team-Ebene, indem das Hook-Skript in das Projekt-Initialisierungstemplate aufgenommen wird.
Ausblick und industrielle Bedeutung
Das Problem offenbart eine grundlegende Design-Asymmetrie: AI-gestützte Codewerkzeuge neigen zu automatischer Bereinigung, ohne den vom Entwickler intendierten Nutzungskontext zu berücksichtigen. Ein Worktree dient nicht nur als Git-Konstrukt, sondern als Arbeitsumgebung – mit Terminalverlauf, Chat-Protokoll und gedanklichem Kontext. Die reine Betrachtung von Git-Änderungen als Kriterium für die Löschung ignoriert diesen immateriellen Wert.
Positiv ist, dass Claude Codes Lock-Mechanismus eine flexible Abwehr ermöglicht. Obwohl der Hersteller keinen Konfigurationsschalter vorsieht, können Teams durch Ausnutzung der nativen Git-Funktionen ein gleichwertiges Verhalten erzwingen. Dies zeigt, dass durchdachte Werkzeuge immer einen Ausweg für „Power-User“ lassen sollten. Künftige Versionen könnten mit einem expliziten `--keep-worktree`-Flag oder einer `worktreeCleanupPolicy`-Option in der Konfigurationsdatei Abhilfe schaffen. Ebenso vielversprechend ist der Community-Vorschlag eines `WorktreeRemove`-Hooks, der vor der Löschung eine benutzerdefinierte Prüfung erlaubt.
Für Teams, die Claude Code intensiv einsetzen, empfiehlt es sich, das Worktree-Locking als Standard-Praxis in das Projekt-Onboarding aufzunehmen. So schützen sie nicht nur temporäre Arbeitsbereiche, sondern vermeiden auch Verwirrung durch versehentlich gelöschte Branches. Kleine technische Details wie diese können die Produktivität eines gesamten Teams nachhaltig steigern.
Sources
FAQ
Wie wird die automatische Worktree-Bereinigung in Claude Code ausgelöst?
Beim Beenden einer --worktree-Sitzung ohne Änderungen, ohne neue Commits und ohne Sitzungsname werden Worktree und Branch stillschweigend gelöscht.
Wie kann man das Löschen des Worktrees verhindern?
Verwenden Sie `git worktree lock`, um den Worktree zu sperren, oder nutzen Sie den SessionStart-Hook zum automatischen Entsperren und erneuten Sperren.
Gibt es eine Konfigurationsoption, um die automatische Bereinigung zu deaktivieren?
Die offizielle Dokumentation betrachtet dies als Designmerkmal und bietet keinen Konfigurationsschalter; nur externe Maßnahmen sind möglich.