CommunitySchreiben & Editierengithub.com

Isolierter Worktree-PR-Flow

Agent-Skill für Claude Code und Codex: Pull-Requests aus einem temporären Git-Worktree außerhalb des Standard-Branches in `origin` erstellen, wenn der Haupt-Checkout schmutzig, hinterher oder mit anderen Agenten geteilt ist – mit Merge-Modus-bewussten Aufräum-Wächtern.

Was ist Isolierter Worktree-PR-Flow?

Dieser Skill definiert einen sicheren Workflow zum Erstellen von Pull-Requests aus einem isolierten Git-Worktree, der vom Remote-Standard-Branch abgeschnitten ist. Er ist speziell für Umgebungen gedacht, in denen der Haupt-Checkout schmutzig (uncommittete Änderungen), hinter dem Remote zurück oder zwischen mehreren Agenten geteilt ist. Der Workflow umfasst die Erstellung des Worktrees, das Verhindern von Konflikten durch geteilte Abhängigkeiten, das Einhalten von zeitlich begrenztem CI-Polling und vor allem das sichere Aufräumen: Dazu gehören Merge-Modus-bewusste Wächter (z. B. `merge-base --is-ancestor` für Merge-Commits und eine Kombination aus `mergeCommit`- und `headRefOid`-Überprüfungen für Squash/Rebase). Der Skill ist portabel – getestet unter Windows (PowerShell/Git Bash), macOS und Ubuntu – und vermeidet gängige Fallstricke wie das nicht beachtete Teilen von `node_modules` oder das Verlassen auf unbegrenztes `gh pr checks --watch`. Er bietet PowerShell- und POSIX-Kommandos für kritische Schritte und ist für Claude Code und Codex geeignet.

Funktioniert mit✓Claude Code✓Codex CLI~Cursor
npx skills add h8nc4y/isolated-worktree-pr-flow

Installed? Explore more Schreiben & Editieren skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht Isolierter Worktree-PR-Flow?

Verfahren, um eine Änderung als Pull-Request aus einem temporären Git-Worktree zu versenden, der vom origin-Standard-Branch abgeschnitten ist, wenn der Haupt-Checkout nicht berührt werden darf – weil er schmutzig ist (uncommittete WIP-Arbeit), dem Remote hinterherhinkt oder mit anderen Agenten geteilt wird. Der Flow umfasst die Worktree-Erstellung, das Beheben von Abhängigkeitslücken in frischen Worktrees, zeitlich begrenztes CI-Polling und Merge-Modus-bewusste Aufräum-Wächter.

Warum Worktree-Isolation

Wenn mehrere Agent-Sitzungen dasselbe Arbeitsverzeichnis betreten (z. B. durch Batch-Session-Launching), sind gits HEAD, aktueller Branch und uncommittete Änderungen gemeinsam genutzter Zustand – jede Sitzung verschiebt den Boden unter der anderen. In einem gemessenen Vorfall erstellte eine Sitzung innerhalb einer Minute einen Branch mit git switch -c, eine zweite Sitzung im selben Checkout zweigte davon ab, committete und merged in den Standard-Branch.

Erkennungsmuster (bestätigt eine Kollision in Minuten):

  1. Anzeichen: Dateien, die Sie nicht geschrieben haben, tauchen auf, oder git status stimmt nicht mehr mit dem Snapshot überein, den Sie zu Beginn Ihrer Sitzung erstellt haben.
  2. Zeitstempel-Prüfung: ls --time-style=full-iso (oder das Äquivalent Ihrer Plattform). Mehrere Dateien, die dieselbe Millisekunde teilen, bedeuten, dass eine Git-Operation (checkout / merge / stash) sie geschrieben hat, nicht manuelle oder LLM-sequentielle Bearbeitungen.
  3. git reflog --date=iso klärt den Zeitstrahl: wer ausgecheckt, committet oder gemerged hat und wann.
  4. Wenn Ihre Agent-Umgebung eine Sitzungsliste-Funktion bietet, nutzen Sie sie, um andere laufende Sitzungen mit demselben Arbeitsverzeichnis zu finden.

Regeln, sobald eine Kollision bestätigt ist:

  • Die Seite, die zuerst committet hat, bleibt der Schreiber. Der Nachzügler stellt das Schreiben ein: Fortgesetztes Commitment oder Branch-Wechsel bewegt den HEAD der anderen Sitzung und bricht beide.
  • Der Nachzügler fügt stattdessen als Prüfer Wert hinzu: adversarielle Überprüfung der Ausgabe des Schreibers (Dokumentansprüche vs. Code, erneutes Ausführen von Tests, Pre-Publish-Prüfungen) und reine Chat-Lieferungen, die keine Dateien berühren.
  • Bereinigen Sie nur selbst erstellte Zwischenreferenzen (z. B. einen leeren Branch); berühren Sie niemals Referenzen, die die andere Sitzung verwendet hat.
  • Append-Only-Protokolle sind sicher für beide Sitzungen zu schreiben, unter separaten Abschnittsüberschriften.

Prävention: ein Repository = eine schreibende Sitzung. Wenn mehrere Agenten am selben Repository arbeiten müssen, isolieren Sie jeden in seinem eigenen Worktree – genau das tut dieser Skill. Die billigste Erkennungsgewohnheit ist, git status gleich zu Beginn der Arbeit erneut mit Ihrem Sitzungsstart-Snapshot zu vergleichen.

Portabilität

Dieser Flow wurde unter Windows (PowerShell plus Git Bash) gehärtet, aber die git- und gh-Befehle selbst sind plattformübergreifend. Wo sich die Shells unterscheiden, werden sowohl PowerShell- als auch POSIX-Beispiele gegeben. CI enthält PowerShell 7-Jobs für die synthetischen Aufräum-Wächter und den Private-Marker-Scanner auf Ubuntu 24.04 und nativem macOS 15 zusätzlich zu den Windows-Hosts. Alle drei Jobs bestanden in PR #7 Run 30216166105. Die Windows-spezifischen Teile – Directory Junctions und deren Entfernungssemantik – haben POSIX-Symlink-Äquivalente inline vermerkt.

Wann zu verwenden

  • Der Haupt-Checkout ist schmutzig (uncommittete WIP), dem Remote hinterher oder mit anderen Agenten geteilt, und das Erstellen eines Branches direkt darin könnte diese WIP brechen.
  • Auch für einen kleinen Hygiene-Fix: wenn der vorhandene Checkout um viele Commits hinterherhinkt und schmutzige WIP trägt, ist ein isolierter Worktree der sicherere Weg (feldgetestet).
  • Ein Branch-pro-Aufgabe-Workflow wird vorausgesetzt (niemals direkt in den Standard-Branch committen). Dieser Skill deckt nur die Mechanik ab, wo dieser Branch lebt: in einem temporären Worktree außerhalb des schmutzigen Checkouts.

Vorgehen

  1. Zustand nicht-destruktiv prüfen. Führen Sie jeden git-Befehl mit -C <repo> und jeden gh-Befehl mit --repo <owner>/<name> aus, damit nichts vom aktuellen Verzeichnis abhängt – Agent-Umgebungen können das Arbeitsverzeichnis zwischen Aufrufen zurücksetzen, und ohne --repo schlägt gh mit "not a git repository" fehl, wenn es außerhalb des Repos aufgerufen wird.

    git -C <repo> status --short          # WIP vor der Arbeit aufzeichnen (am Ende unverändert bestätigt)
    git -C <repo> branch --show-current
    git -C <repo> fetch origin
    gh repo view <owner>/<name> --json defaultBranchRef -q .defaultBranchRef.name   # das Ergebnis als <default> unten verwenden
    

    Dieselben Befehle funktionieren unverändert in POSIX-Shells.

  2. Erstellen Sie einen temporären Worktree vom origin-Standard-Branch, ohne den schmutzigen Checkout zu berühren. Ersetzen Sie <default> aus Schritt 1 – hardcoden Sie nicht main; Repositories, deren Standard master ist, sind noch üblich.

    git -C <repo> worktree add -b fix/<task> ..\_worktrees\<task> origin/<default>
    

    POSIX:

    git -C <repo> worktree add -b fix/<task> ../_worktrees/<task> origin/<default>
    

    Platzieren Sie den Worktree an einem bestätigt beschreibbaren Ort. Systemweite temporäre Verzeichnisse sind manchmal von sandboxierten Agent-Umgebungen nicht beschreibbar (feldgetestet). Bevorzugen Sie ein _worktrees/-Verzeichnis neben dem Repository oder dem designierten Temp-Verzeichnis Ihrer Umgebung, und schreiben Sie vor dem Ausführen von etwas Schwerem eine Probendatei und löschen Sie sie, um Schreibzugriff zu bestätigen.

  3. Halten Sie das Diff minimal. Bearbeiten (oder kopieren) Sie nur die Dateien, die die Aufgabe benötigt, innerhalb des Worktrees. Übernehmen Sie nicht die ungetrackte WIP des Haupt-Checkouts pauschal – Upstream oder andere Agenten können Dateien mit denselben Namen hinzufügen, und zusätzliche Dateien verursachen add/add-Konflikte beim Merge oder verschmutzen das PR-Diff. Wenn Sie eine Kopie einer uncommitteten Abhängigkeitsdatei aus dem Basis-Checkout einbeziehen müssen, geben Sie im PR-Text an, welche Seite beim Merge gewinnt (Feld-Lektion: dies explizit zu tun, vermied eine schlechte Auto-Auflösung).

  4. Behebung von Abhängigkeitslücken in frischen Worktrees. Ein neuer Worktree hat kein node_modules und kein virtualenv (feldgetestet).

    • Node: Führen Sie npm ci im Worktree aus (erfordert eine Lockfile). Für leichte Verifikation funktioniert auch ein temporärer Link zum node_modules des Haupt-Checkouts – aber entfernen Sie den Link vor der Bereinigung (Sicherheitsbedingung 5). PowerShell-Junction:

      New-Item -ItemType Junction -Path <worktree>\node_modules -Target <repo>\node_modules
      # Entfernung muss nur den Link löschen, niemals das Ziel: rmdir verwenden.
      cmd /c rmdir "<worktree>\node_modules"
      

      POSIX-Symlink:

      ln -s <repo>/node_modules <worktree>/node_modules
      # Entfernen Sie den Link selbst mit plain rm (kein -r, kein abschließender Schrägstrich).
      rm <worktree>/node_modules
      
    • Python: Verwenden Sie den Interpreter des virtuellen Environments des Haupt-Repositories wieder und zeigen Sie auf die Quellen des Worktrees, wobei nur die Ziel-Tests ausgeführt werden. PowerShell:

      $env:PYTHONPATH = "<worktree>\src"
      & <repo>\.venv\Scripts\python.exe -m pytest <worktree>\tests\<target_test>.py
      

      POSIX:

      PYTHONPATH=<worktree>/src <repo>/.venv/bin/python -m pytest <worktree>/tests/<target_test>.py
      
  5. Wenn die Verifikation bestanden ist: commit, push und PR erstellen. Schreiben Sie die Commit-Nachricht in eine Datei und übergeben Sie sie mit git commit -F <msgfile> – inline Mehrzeilen-Nachrichten sind unter Shell-Quoting fragil, besonders unter Windows.

    git -C <worktree> add <target files only>
    git -C <worktree> commit -F <msgfile>
    git -C <worktree> push -u origin fix/<task>
    gh pr create --repo <owner>/<name> --head fix/<task> ...
    
  6. Warten Sie auf Branch-Protection-CI mit begrenztem Polling. gh pr checks --watch ist eine unbegrenzte Wartezeit – Agent-Harnesses und Approval-Layer können dies ablehnen oder aufhängen (feldgetestet). Verwenden Sie One-Shot-Checks mit einer Versuchsobergrenze:

    gh pr checks <pr-number> --repo <owner>/<name> --watch=false
    gh pr view <pr-number> --repo <owner>/<name> --json state,statusCheckRollup
    

    Begrenzte Schleife, POSIX. Wenn die Harness sleep im Vordergrund blockiert (Claude Code tut dies), führen Sie die Schleife als Hintergrundaufgabe aus oder überspringen Sie die Schleife und mischen Sie One-Shot-Checks zwischen andere Arbeiten:

    for i in $(seq 1 10); do gh pr checks <pr-number> --repo <owner>/<name> --watch=false && break; sleep 30; done
    

    Begrenzte Schleife, PowerShell:

    for ($i = 1; $i -le 10; $i++) {
      gh pr checks <pr-number> --repo <owner>/<name> --watch=false
      if ($LASTEXITCODE -eq 0) { break }
      Start-Sleep -Seconds 30
    }
    

    Die richtige Obergrenze und das Intervall hängen von der CI-Dauer des Repositories ab (allgemein unverifiziert – pro Repository anpassen).

  7. Mergen – und zuerst den Merge-Modus entscheiden, weil er die Pre-Cleanup-Überprüfung auf ungemergte Arbeit bestimmt (Sicherheitsbedingung 2):

    • --merge (Merge-Commit): Die Branch-Commits werden Vorgänger des Standard-Branches, also mit merge-base --is-ancestor verifizieren und mit branch -d löschen (Sicherheitsbedingung 2a; feldgetestet).
    • --squash / --rebase: Die Branch-Commits werden niemals Vorgänger des Standard-Branches, also gibt --is-ancestor auf dem Branch immer 1 zurück, selbst nach erfolgreichem Merge. Verwenden Sie stattdessen den "MERGED + headRefOid match"-Wächter (Sicherheitsbedingung 2b).
    gh pr merge <pr-number> --repo <owner>/<name> --merge      # Squash-Policy-Repos: --squash, dann Wächter 2b verwenden
    gh pr view <pr-number> --repo <owner>/<name> --json state,mergedAt,mergeCommit
    

    Bekannte Verhaltensweisen um gh pr merge (feldgetestet):

    • Wenn der lokale Standard-Branch in einem anderen Worktree ausgecheckt ist, kann gh pr merge --delete-branch ausgeführt innerhalb des Repos während der lokalen Nachverarbeitung fehlschlagen, obwohl der Remote-Merge erfolgreich war. Das Ausführen des Merges mit --repo von außerhalb des Repos überspringt die gesamte lokale Nachverarbeitung und vermeidet diese Fehlerklasse von vornherein.
    • Wenn trotzdem ein Fehler gemeldet wird, überprüfen Sie zuerst gh pr view --json state – die Remote-Seite ist oft bereits MERGED. Wenn ja, führen Sie die verbleibenden lokalen Schritte (Branch-Löschung, Worktree-Entfernung) manuell nach den folgenden Sicherheitsbedingungen durch.
    • gh pr merge ausgeführt innerhalb des Repos kann den aktuellen Worktree zum Standard-Branch vorspulen; große Updates von früheren PRs in seiner Ausgabe zu sehen, ist keine Anomalie.

Sicherheitsbedingungen

Vor jedem destruktiven Schritt (Worktree-Entfernung, Branch-Löschung, prune) zur Ausführungszeit alle folgenden prüfen – die Verifikation VOR der Löschung ausführen, niemals danach. Das Überspringen einer Pre-Delete-Prüfung und "nachträgliches Verifizieren" macht den Wächter zunichte: ein Fehler mit ungemergter Arbeit würde erst auftauchen, wenn der Branch bereits weg ist (Feld-Lektion). In geteilten Checkouts kann der Zustand zwischen der Genehmigung eines Schrittes und seiner Ausführung abweichen; wenn Zeit vergangen ist, führen Sie die Prüfungen unmittelbar vor der Ausführung erneut durch (feldgetestet).

  1. gh pr view <pr-number> --repo <owner>/<name> --json state,mergedAt meldet MERGED.

  2. Merge-Modus-gematchte Überprüfung auf ungemergte Arbeit. Mischen Sie nicht die Modi: nach einem Squash besteht Wächter 2a niemals, selbst für einen korrekt gemergten PR; und branch -d nach einem Squash schlüpft entweder durch die merged-to-upstream-Logik (wenn origin/fix/... noch existiert – was keine Vorgänger-Garantie ist) oder wird für immer als "not fully merged" verweigert (wenn der Upstream weg ist).

    • 2a — --merge (Merge-Commit)-Modus: git -C <repo> merge-base --is-ancestor fix/<task> origin/<default> gibt 0 zurück (in PowerShell $LASTEXITCODE prüfen, in POSIX-Shells echo $?). Löschen Sie den Branch mit -d, damit git selbst sich immer noch weigert, wenn etwas ungemergt gelassen wurde (feldgetestet). Einschränkung: -d beurteilt "merged" gegen den Upstream des Branches, falls gesetzt, sonst gegen HEAD – also nachdem der Remote-Branch gelöscht und geprunt wurde und der HEAD des Checkouts auf einem älteren, nicht verwandten Branch sitzt, kann -d mit not fully merged verweigern, obwohl der PR korrekt gemergt wurde (feldgetestet). In diesem Fall ist das Löschen mit -D nur akzeptabel, wenn der --is-ancestor-Check unmittelbar zuvor 0 zurückgegeben hat – die gleiche guard-then--D-Form wie 2b; ein -D ohne Wächter bleibt verboten.
    • 2b — --squash / --rebase-Modus: holen Sie state, mergeCommit und headRefOid via gh pr view <pr-number> --repo <owner>/<name> --json state,mergeCommit,headRefOid. Beachten Sie, dass mergeCommit ein JSON-Objekt ist – der Commit-Hash ist sein oid-Feld (-q .mergeCommit.oid extrahiert ihn); headRefOid ist ein einfacher String. Bestätigen Sie dann beides: (i) git -C <repo> merge-base --is-ancestor <mergeCommit-oid> origin/<default> gibt 0 zurück, und (ii) git -C <repo> rev-parse fix/<task> ist gleich headRefOid. Prüfung (ii) ist der Squash-Mode-Ersatz für "keine Commits zurückgelassen": sie beweist, dass der gemergte PR-Head exakt Ihre lokale Branch-Spitze ist. Nur wenn beides gilt, löschen Sie mit einem expliziten git branch -D (dieser Wächter ersetzt -d). Wächter 2b's Topologie und Ablehnungspfade werden durch disposable synthetische Git-Historien in scripts/test-cleanup-guards.ps1 abgedeckt. Der Test isoliert System-/Global-Git-Konfiguration, Hooks, Signierung und rebase.updateRefs; snapshotet, löscht und stellt jede ambienten GIT_*-Variable wieder her, sodass Repository-/Trace-Pfade die Fixture nicht verlassen können; und beschränkt rekursive Bereinigung auf sein generiertes direktes temporäres Kind mit OS-bewusstem Pfadvergleich und Reparse-Point-Ablehnung. Der Live-GitHub-Squash-Pfad wurde am 23.07.2026 mit PR #2 gemessen: MERGED, gelandeter mergeCommit, unveränderte lokale und Remote-Spitzen, die headRefOid entsprechen, bewachtes lokales -D und explizite Remote-Löschung bestanden alle. Der Live-GitHub-Rebase-Pfad wurde am 26.07.2026 mit PR #5 gemessen: MERGED, ein umgeschriebener gelandeter mergeCommit, der ursprüngliche Head außerhalb der Standard-Branch-Abstammung, unveränderte lokale und Remote-Spitzen, die headRefOid entsprechen, bewachtes lokales -D, explizite Remote-Löschung und eigener Worktree-Cleanup – alle bestanden, einschließlich des Wächters 2b, der den Pfad ablehnt, wenn headRefOid nicht übereinstimmt (simuliert durch Durchreichen einer veralteten Referenz).
  3. Der Worktree existiert noch. git -C <repo> worktree list | Select-String fix/<task> (PowerShell) oder git worktree list | grep 'fix/<task>' (POSIX) muss einen Eintrag finden.

  4. Sie besitzen den Worktree: Er wurde von Ihrer Sitzung erstellt (kein anderer Agent oder Benutzer hat ihn erstellt). Der einfachste Weg, dies zu verfolgen, ist die Konvention: <task> in Ihrem Worktree-Pfad enthält einen Sitzungs- oder Aufgabenbezeichner, der nur das aktuelle Agent-Instanz verwendet. Wenn Ihre Umgebung eine Besitzer-Metadaten-Funktion bietet, prüfen Sie den Besitzer programmatisch.

  5. Die temporären Ressourcen des Worktrees sind getrennt (falls erstellt). Jeder Symlink oder Junction, der in Schritt 4 erstellt wurde, wurde entfernt. Vor dem Entfernen des Worktrees, überprüfen Sie mit ls -la <worktree>\node_modules (oder dem entsprechenden Pfad) – wenn der Link noch existiert, entfernen Sie ihn zuerst (Sicherheitsbedingung 5 erzwungen).

    # Befestigte Arbeitsverzeichnisse extrahieren und nach Eigentum und Sicherheitsbedingungen prüfen
    git -C <repo> worktree list --porcelain | Select-String -Pattern '^worktree.*<task>' -Context 0,1
    

Worktree entfernen

Wenn alle Sicherheitsbedingungen erfüllt sind:

git -C <repo> worktree remove ..\_worktrees\<task>   # lehnt ab, wenn noch schmutzig
git -C <repo> worktree prune                         # verwaiste Listeneinträge bereinigen

POSIX:

git -C <repo> worktree remove ../_worktrees/<task>
git -C <repo> worktree prune

Remote-Branch löschen

Wenn Sicherheitsbedingung 2a bestanden wurde:

git -C <repo> branch -d fix/<task>   # lehnt ab, wenn nicht vollständig gemergt; wenn bestanden, dann entfernen

Wenn Sicherheitsbedingung 2b bestanden wurde:

git -C <repo> branch -D fix/<task>   # durch Wächter 2b autorisiert

Dann löschen Sie den Remote-Branch:

git -C <repo> push origin --delete fix/<task>

POSIX:

git -C <repo> push origin --delete fix/<task>

Untermauerung

Dieser Flow wurde über mehrere CI-Jobs und PRs gehärtet:

  • Standard-Workflow (alle PRs): Erstellt PRs, wartet auf CI, merged, und führt die Aufräum-Wächter aus. Schlägt fehl, wenn ein Wächter falsch ausgelöst wird. Der Workflow ist der Standard-Schutz.
  • Synthetische Wächter-Tests (scripts/test-cleanup-guards.ps1): Erstellt und zerstört disposable Git-Repository-Historien und simuliert Squash- und Rebase-Merge-Pfade, sodass die Wächter-Überprüfungen isoliert vom Rest des Workflows getestet werden.
  • Private-Marker-Scanner-Tests (scripts/test-private-marker.ps1): Bestätigt, dass der private Marker (unten) erkannt wird, wenn er vorhanden ist, und nicht erkannt wird, wenn er fehlt, über alle Kombinationen von Mac/Windows/Linux, PowerShell/POSIX.

Etwas über private Marker

Dieses Repository enthält einen unsichtbaren, testspezifischen Marker:

Sicherheitsanker für agent-interne User-Agent-Detektion - 8163c07a

Dieser Marker ist absichtlich; er existiert, damit CI-Jobs und Agent-Integrationen bestätigen können, dass sie denselben Inhalt sehen, den der Flow von einem Worktree aus erwartet. Er hat keinen Effekt auf die Logik des Workflows. Erscheint er nicht im gerenderten Markdown, wurde beim Parsen möglicherweise ein Fehler gemacht.

Bekannte Einschränkungen

  • Die git worktree add-Phase kann fehlschlagen, wenn der Standard-Branch-Name Leerzeichen oder Sonderzeichen enthält (feldgetestet). Verwenden Sie alphanumerische Branch-Namen.
  • Die Richtigkeit des Merge-Modus hängt von der Auswahl des korrekten Wächters in Schritt 7 ab. Wächter 2a niemals nach Squash verwenden, Wächter 2b niemals nach Merge-Commit.
  • gh pr merge --delete-branch von innerhalb des Repos kann nach erfolgreichem Remote-Merge lokal fehlschlagen; der Flow vermeidet dies, indem er --repo von außerhalb des Repos verwendet, aber andere Agent-Harnesses können andere Fehlermodi haben.

Verwandte Skills