Alle Artikel

Git Worktrees: Ein praktischer Leitfaden mit Lazygit und Yazi

GitTutorialDevTools
Git Worktrees: Ein praktischer Leitfaden mit Lazygit und Yazi

Was sind Git Worktrees?

Git Worktrees ermöglichen es, mehrere Branches gleichzeitig ausgecheckt in verschiedenen Verzeichnissen zu haben. Anstatt Arbeit zu stashen oder unfertigen Code zu committen, um den Branch zu wechseln, wechseln Sie einfach mit cd in einen anderen Ordner.

Bei einem normalen Git-Workflow kann Ihr Repository immer nur einen Branch ausgecheckt haben. Mit Worktrees lebt jeder Branch in seinem eigenen Verzeichnis, aber sie teilen sich alle dieselbe Git-Historie. Commits, Stashes und Remotes werden zwischen allen Worktrees geteilt.

Zwei Ansätze für Worktrees

Ansatz A: Worktrees zu einem bestehenden Repo hinzufügen

Sie behalten Ihren aktuellen Clone und fügen Worktrees daneben hinzu. Schnell gestartet, aber der Haupt-Worktree ist ein regulärer Clone mit einem .git-Ordner, was ihn strukturell von den anderen unterscheidet.

Ansatz B: Bare Clone + Worktrees (Empfohlen)

Sie erstellen einen Bare Clone (ohne Arbeitsverzeichnis) und fügen dann Worktrees für jeden Branch hinzu, einschließlich Main. Dies ist der eigentliche Worktree-Workflow: Alle Branches sind gleichwertig, und das Bare Repo ist nur eine gemeinsame Git-Datenbank.

Wir verwenden Ansatz B, weil er eine saubere, symmetrische Struktur bietet, in der kein Branch eine Sonderstellung hat.

Einen Bare Clone einrichten

Schritt 1: Bare Clone erstellen

Der Wrapper-Ordner ersetzt Ihren regulären Clone, verwenden Sie daher denselben Projektnamen, den Sie immer verwendet haben:

cd ~/Work/my-org
mv my-project my-project-old

mkdir my-project
cd my-project
git clone --bare <repo-url> .bare

Vielleicht möchten Sie dem Wrapper-Ordner ein Suffix wie -wt oder .git geben, um ihn von einem regulären Clone zu unterscheiden. Tun Sie das nicht. Sobald Sie sich für Worktrees entschieden haben, ist dies Ihr Repo. Ein Suffix ist nur unnötiger Ballast, den Sie jeden Tag tippen.

Schritt 2: .git-Pointer einrichten

echo "gitdir: ./.bare" > .git

Dies erstellt eine .git-Datei (kein Verzeichnis), die Git mitteilt, dass das eigentliche Repo in .bare liegt. Git-Befehle funktionieren jetzt vom Wrapper-Ordner aus.

Schritt 3: Remote-Fetch-Refs konfigurieren

Standardmäßig ruft ein Bare Clone Remote-Branch-Refs nicht korrekt ab. Das korrigieren wir:

git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"

Schritt 4: Alles abrufen

git fetch origin

Jetzt haben Sie die vollständige Repo-Historie und können Worktrees erstellen.

Worktrees erstellen und verwalten

Erstellen Sie Ihren ersten Worktree für den Main-Branch:

git worktree add main

Dies erstellt ein main/-Verzeichnis mit dem ausgecheckten Branch. Für Feature-Branches:

# Bestehender Branch
git worktree add feature-branch

# Neuer Branch
git worktree add -b my-new-feature my-new-feature

Zum Auflisten, Entfernen und Aufräumen:

# Alle Worktrees auflisten
git worktree list

# Worktree entfernen (Branch bleibt erhalten)
git worktree remove feature-branch

# Branch ebenfalls löschen
git branch -d feature-branch

# Veraltete Referenzen bereinigen
git worktree prune

Die Verzeichnisstruktur

Nach der Einrichtung sieht Ihr Projekt so aus:

my-project/                  # Wrapper (hier arbeiten Sie nicht direkt)
├── .bare/                   # Git-Datenbank (von allen Worktrees geteilt)
├── .git                     # Datei, die auf .bare zeigt
├── .shared/                 # Gitignorierte Dateien, symlinked in Worktrees
│   └── .env
├── new-worktree.sh          # Hilfsscript
├── main/                    # Worktree: Main-Branch (sauber halten)
│   ├── .env -> ../.shared/.env
│   ├── src/
│   └── package.json
└── feature-branch/          # Worktree: Feature-Branch (hier arbeiten)
    ├── .env -> ../.shared/.env
    ├── src/
    └── package.json

Jeder Worktree hat eigene node_modules, Build-Ausgaben und Arbeitszustand. Sie sind völlig unabhängige Verzeichnisse. In jedem muss npm install ausgeführt werden.

Lazygit-Integration

Lazygit hat eingebaute Worktree-Unterstützung. Öffnen Sie es aus einem beliebigen Worktree-Verzeichnis und es erkennt das Setup automatisch.

Das Worktrees-Panel finden

Der Worktrees-Tab befindet sich im Branches-Panel:

  1. Drücken Sie 3 um das Branches-Panel zu öffnen
  2. Wechseln Sie Sub-Tabs mit ] (weiter) und [ (zurück): Lokale Branches → Remotes → Tags → Worktrees

Beachten Sie, dass die w-Taste kontextabhängig ist: Im Files-Panel committet sie staged Dateien, im Branches-Panel erstellt sie einen Worktree vom ausgewählten Branch. Sie öffnet kein Worktrees-Panel.

Worktree-Aktionen

Vom Worktrees-Tab aus:

  • Enter — Zum ausgewählten Worktree wechseln
  • n — Neuen Worktree erstellen
  • d — Ausgewählten Worktree entfernen
  • ? — Alle Tastenbelegungen anzeigen (funktioniert in jedem Panel)

Side-by-Side-Diffs mit Delta

Lazygit hat keine eingebaute Split-Diff-Ansicht, aber Sie können Side-by-Side-Diffs erhalten, indem Sie Delta als benutzerdefinierten Pager verwenden:

brew install git-delta

Dann erstellen Sie die Lazygit-Konfiguration (macOS: ~/Library/Application Support/lazygit/config.yml, Linux: ~/.config/lazygit/config.yml):

git:
  paging:
    colorArg: always
    pager: delta --dark --paging=never --side-by-side

Alle Diffs in Lazygit werden jetzt side-by-side mit Syntax-Highlighting angezeigt. Drücken Sie e in einer Diff-Ansicht, um die Datei in Ihrem $EDITOR zu öffnen.

Nicht-US-Tastaturlayouts

Die [- und ]-Tasten zum Tab-Wechsel sind auf nicht-US-Tastaturen schwer erreichbar:

  • Deutsch Mac: [ = Option+5, ] = Option+6
  • Deutsch Windows/Linux: [ = AltGr+8, ] = AltGr+9

Yazi-Integration

Yazi ist ein Terminal-Dateimanager, der gut mit Worktrees harmoniert. Da alle Branches Geschwister-Verzeichnisse sind, können Sie visuell zwischen ihnen navigieren.

# Yazi im Wrapper-Ordner öffnen
cd my-project
yazi

Tab-basierter Workflow

Der empfohlene Aufbau ist ein Yazi-Tab pro aktivem Worktree:

  1. Öffnen Sie Yazi im Wrapper-Ordner
  2. Gehen Sie in main/ → drücken Sie t für einen neuen Tab
  3. Zurück mit h, dann in feature-x/ → erneut t drücken
  4. Wechseln Sie zwischen Tabs mit 1 und 2
  5. Tab schließen mit Ctrl+c

Befehle aus Yazi heraus ausführen

  • ; — Befehl im Hintergrund ausführen (nicht blockierend, ideal für npm start)
  • : — Befehl im Vordergrund ausführen (blockierend, ideal für npm install)
  • w — Task-Manager öffnen (Hintergrund-Tasks anzeigen)
  • Enter (im Task-Manager) — Task-Logs anzeigen
  • x (im Task-Manager) — Task abbrechen
  • q (im Task-Manager) — Zurück zu Yazi

So können Sie einen Dev-Server mit ; starten, npm start eingeben und weiter Dateien durchsuchen, während er läuft.

Gitignorierte Dateien zwischen Worktrees teilen

Ein kritisches Detail, das viele überrascht: Gitignorierte Dateien werden nicht zwischen Worktrees geteilt. Jeder Worktree ist sein eigenes Verzeichnis auf der Festplatte. Dateien wie .env, IDE-Konfigurationen oder Tool-Einstellungen existieren nur in dem Worktree, in dem Sie sie erstellt haben.

Die Symlink-Lösung

Halten Sie gemeinsam genutzte gitignorierte Dateien in einem .shared/-Verzeichnis im Wrapper-Ordner und verlinken Sie sie per Symlink in jeden Worktree:

mkdir .shared
cp main/.env .shared/.env

# In bestehende Worktrees symlinken
ln -s "$(pwd)/.shared/.env" main/.env
ln -s "$(pwd)/.shared/.env" feature-branch/.env

Eine einzige Quelle der Wahrheit, und jeder Worktree sieht dieselbe Datei. Bearbeitung in einem Worktree ändert sie überall, da alle auf denselben Ort zeigen.

Teilen: Konfiguration und Tooling (.env, .editorconfig, Tool-Einstellungen). Separat halten: Generierte Dateien (node_modules, dist, Build-Caches).

Der Trailing-Slash-Fallstrick

Wenn Ihre .gitignore einen Trailing Slash verwendet, um Verzeichnisse zu ignorieren:

.myconfig/

Dies erfasst keine Symlinks auf Verzeichnisse. Git behandelt Symlinks als Dateien, daher passt .myconfig/ nur auf ein echtes Verzeichnis. Der Symlink taucht als untracked auf.

Lösung: Trailing Slash entfernen:

.myconfig

Dies erfasst Verzeichnisse, Dateien und Symlinks. Überprüfen Sie Ihre globale Gitignore und entfernen Sie Trailing Slashes von Mustern, die als Symlinks vorkommen könnten.

Automatisierung mit einem Hilfsscript

Symlinks manuell zu erstellen wird schnell lästig. Platzieren Sie ein Hilfsscript im Wrapper-Ordner:

#!/usr/bin/env bash
set -euo pipefail

if [ $# -eq 0 ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
  echo "Usage: ./new-worktree.sh <branch-name> [--new]"
  echo ""
  echo "  <branch-name>        Bestehenden Branch auschecken"
  echo "  <branch-name> --new  Neuen Branch und Worktree erstellen"
  echo ""
  echo "Alle Dateien in .shared/ werden in neue Worktrees symlinked."
  exit 0
fi

BRANCH_NAME="$1"
CREATE_NEW="${2:-}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SHARED_DIR="$SCRIPT_DIR/.shared"
WORKTREE_DIR="$SCRIPT_DIR/$BRANCH_NAME"

if [ "$CREATE_NEW" = "--new" ]; then
  git worktree add -b "$BRANCH_NAME" "$WORKTREE_DIR"
else
  git worktree add "$WORKTREE_DIR" "$BRANCH_NAME"
fi

if [ -d "$SHARED_DIR" ]; then
  for item in "$SHARED_DIR"/.[!.]* "$SHARED_DIR"/*; do
    [ -e "$item" ] || continue
    name="$(basename "$item")"
    target="$WORKTREE_DIR/$name"
    if [ ! -e "$target" ]; then
      ln -s "$item" "$target"
      echo "  Linked: $name"
    else
      echo "  Skipped (exists): $name"
    fi
  done
fi

echo "Worktree ready: $WORKTREE_DIR"

Jetzt bekommt jeder neue Worktree automatisch alle gemeinsam genutzten Dateien per Symlink.

Täglicher Workflow

Halten Sie Ihren Main-Worktree sauber als stabile Baseline. Arbeiten Sie in Feature-Worktrees:

main/              ← sauber halten, hier pullen, Branches erstellen
feature/something/ ← hier tatsächlich arbeiten
feature/other/     ← eine weitere Aufgabe

Ein neues Feature starten

./new-worktree.sh feature/my-feature --new
cd feature/my-feature
npm install
npm start

Kontext wechseln

Kein Stashen, kein WIP-Committen. Einfach:

# Terminal
cd ../main

# Lazygit: Branches-Panel (3) → Worktrees-Tab (]) → Enter
# Yazi: Zum Geschwister-Verzeichnis navigieren

Code Review

git fetch origin
git worktree add pr-review origin/someones-branch
cd pr-review
npm install && npm start
# Reviewen, testen, fertig
git worktree remove pr-review

Tipps und Fallstricke

  • Same-Branch-Regel: Zwei Worktrees können nicht denselben Branch ausgecheckt haben.
  • Geteilter Git-Status: Commits und Stashes werden geteilt. Ein Commit in einem Worktree ist von allen anderen sichtbar.
  • Separate Dependencies: Jeder Worktree braucht sein eigenes npm install.
  • IDE-Handling: Öffnen Sie Ihre IDE in einzelnen Worktree-Ordnern, nicht im Wrapper. VS Code kommt gut mit der .git-Datei zurecht; andere IDEs benötigen möglicherweise Konfiguration.
  • Aufräumen: Entfernen Sie Worktrees, die Sie nicht mehr brauchen. Führen Sie regelmäßig git worktree prune aus, um veraltete Referenzen zu bereinigen.

Möchten Sie mehr erfahren?

Lassen Sie uns besprechen, wie diese Technologien Ihrem Unternehmen helfen können.