Files
nanobot-runtime/projects/devops/artifacts/2026-09-20_git-worktrees-guide.md
2026-09-20 14:14:28 +02:00

14 KiB

Git worktrees — praktická učebnice

Zdroje: git-scm.com/docs/git-worktree, VS Code docs (branches-worktrees, 9/16/2026), Claude Code docs (worktrees). Vše ověřeno fetchem 2026-09-20.


1. Co worktree je (mental model)

  • Jedna repository (jeden .git adresář, jedna historie, branches, tags, remote) — několik working directories.
  • Primary worktree = klasický checkout. Linked worktree = další adresář, který sdílí tu samou historii, ale má vlastní soubory, staging area a vlastní checked-out branch.
  • Git zakazuje mít jeden branch checkoutnutý ve dvou worktrees zároveň — konflikt je vyloučen konstrukcí.
  • Sdílené: historie, branches, tags, remotes, .git/config, stash.
  • Nesdílené: soubory na disku, index, uncommitted changes.
  • Nesrovnávat s clone: worktree nespotřebuje druhou kopii historie (hardlinked objects), nemá vlastní remote fetch, jeden git fetch platí pro všechny.
  • Praktický důsledek: gitignorované soubory se v novém worktree NEduplikují.env, node_modules, build outputy tam nejsou. Řešení viz níže.

2. CLI — kompletní kuchařka

Základní lifecycle

# výpis
git worktree list
#   /home/user/proj         a1b2c3d [main]        <- primary
#   /home/user/proj-wt-fix  e4f5g6h [fix/leak]     <- linked

# nový worktree na nové branch (typicky hlavní užití)
git worktree add ../proj-fix -b fix/leak

# nový worktree na existující branch
git worktree add ../proj-main main      # pozor: musí být volná (nesmí být checkoutnutá jinde)

# detachnutý (na konkrétním commitu, bez branch)
git worktree add ../proj-hotfix <commit-ish>

Konvence umístění

Dvě osvědčené školy:

  1. Vedle repa (../proj-fix, ../proj-auth) — vhodné, když chceš každý worktree otevřít v jiné instanci editoru/IDE.
  2. Pod jedním rodičovským adresářem pro worktrees (../proj/.worktrees/ nebo ~/worktrees/proj/), primární checkout zůstává čistý. Pozn.: Claude Code umísťuje své worktrees do .claude/worktrees/<name>/ uvnitř repa.
  3. (Pozor na .gitignore — worktree adresáře uvnitř repa musí být ignorované, jinak se Git snaží trackovat jejich obsah.)

Denní provoz

cd ../proj-fix            # pracuj úplně normálně
git status                # funguje, vidí jen tenhle worktree
git add -A && git commit -m "fix"
git push -u origin fix/leak   # sdílený remote, funguje

Úklid

# bezpečné odstranění (odmítne, pokud jsou uncommitted změny)
git worktree remove ../proj-fix

# s násilím (zneužívej vědomě)
git worktree remove --force ../proj-fix

# worktree už je smazaný ručně (rm -rf) -> vyčistit admin metadata
git worktree prune

Když to spadne (recovery)

  • Branch zůstala po remove viset — branch nezávisí na worktree; smaž ji klasicky: git branch -d fix/leak (nebo -D pro nemergenutou).
  • git worktree list ukazuje mrtvé worktreesgit worktree prune (git je nakonec pročistí sám dle gc.worktreePruneExpire, výchozí ~3 měsíce).
  • Nemůžeš checkoutnout branch (already checked out in ...) → je checkoutnutá v jiném worktree: buď tam pokračuj, nebo tam dáš git switch jinam, nebo git worktree add --force (riskantní — stejná branch na dvou místech pak může divergovat).
  • Chceš zjistit, v čem je rozdíl oproti main → vše funguje standardně: git diff main...fix/leak, git log main..fix/leak.

LVM/Zabbix tipy pro homelab kontext

  • worktrees sdílejí .git přes hardlinky → dvě kopie velkého repa na disku netvoří (přesto, du -sh počítá hardlinky dřív jen jednou — na velkých repos zkontroluj du -sh --apparent-size).
  • git gc a git worktree prune v primary worktree spravují metadata všech linked worktrees.
  • Změna commitu v primary neovlivní soubory v linked worktree — na testování dvou verzí side-by-side ideální.

Vzorce pro denní použití

Chci Příkaz
Paralelně: hotfix do main + feature git worktree add ../proj-hotfix -b hotfix/prod-quirk
Code review v čistém stavu git worktree add ../proj-review origin/pr-42
Spustit starou verzi (demo/debug) git worktree add ../proj-v1.0 v1.0
Bisect bez ztráty workspace git worktree add ../proj-bisect (detached)

3. VS Code — built-in podpora (ne extension)

VS Code má nativní podporu worktrees — Source Control view → Repositories → kontext menu repa → Worktrees → Create Worktree.

Postup vytvoření

  1. Otevři Source Control view (Ctrl+Shift+G).
  2. Rozbal Repositories sekci (je-li skrytá, přes ... menu view).
  3. Reprodukovatelně: klikni na repozitář → ... (More Actions) → Worktrees → Create Worktree.
  4. Dialog: vyber branch + zadefinuj cestu (VS Code složku vytvoří a branch do ní checkoutne).
  5. Nový worktree se objeví jako samostatná položka v Repositories view.

Otevírání a switch

  • Každý worktree otevřeš jako samostatnou složku = samostatné VS Code okno (doporučeno; každé okno má vlastní terminál, debug, problems).
  • Cesty: File → Open Recent pro rychlý přístup; v Repositories view pravým na worktree → Open Worktree in New Window / Current Window; Command Palette: Git: Open Worktree in New Window.
  • VS Code automaticky pozná, že otevřená složka je worktree (čte .git file → gitdir pointer).

Nastavení, které se vyplatí

// settings.json
{
  // kopírovat gitignorované soubory do nového worktree (glob patterns)
  "git.worktreeIncludeFiles": [".env", "node_modules/**"],

  // automaticky detekovat worktrees vytvořené mimo VS Code (např. z CLI)
  "git.detectWorktrees": true,
  "git.detectWorktreesLimit": 50   // default
}
  • git.worktreeIncludeFiles — glob; soubor se zkopíruje jen pokud matchne pattern A je gitignorovaný. Typické: .env, node_modules/** (ušetří reinstall), venv/** pozor na absolutní cesty ve scripthích (activate skripty obsahují absolutní cesty — radši nový venv).
  • git.detectWorktrees — pokud worktrees zakládáš z CLI, zapni; jinak VS Code vidí jen ty vytvořené přes GUI.

Další GUI schopnosti

  • Compare with Workspace — pravým na změněný soubor v worktree → diff oproti hlavnímu workspace, side-by-side.
  • Migrate Worktree Changes (Command Palette) — zmerguje všechny změny z worktree do aktuálního workspace.

Gotchas

  • Multi-root workspace se všemi worktrees v jednom okně je technicky možný, ale search/Go-to-Definition ti bude míchat cesty — preferuj jedno okno per worktree.
  • Search (Ctrl+Shift+F) jede na workspace složku, ne na repozitář — nečte automaticky worktrees mimo otevřenou složku.
  • git.worktreeIncludeFiles neřeší .env typu "každý worktree jiný" — to je pořád ruční práce.

4. Claude Code — --worktree / -w (v2.1.49+)

Založení izolované session

cd ~/src/repo
claude --worktree fix-leak       # nebo -w fix-leak
# -> vytvoří .claude/worktrees/fix-leak/
#    na branchi worktree-fix-leak (z remote default branch, typicky origin/main)

claude -w fix-leak -p "..."      # non-interactive; -p přeskočí trust dialog
  • Další terminál + jiné jméno = druhá paralelní session. Bez jména vygeneruje náhodné (typicky bright-running-fox styl).
  • Interactive mód vyžaduje workspace trust — poprvé v adresáři spusť claude bez flagů a přijmi trust dialog, jinak --worktree spadne na erroru. -p (headless) trust check nedělá.
  • Uvnitř session můžeš Claude říct "work in a worktree" → použije nástroj EnterWorktree (před vstupem do worktree mimo .claude/worktrees/ se ptá na approval).

Co je uvnitř a co chybí

  • Worktree = fresh checkout (tracked soubory) — .env, node_modules, build cache ne. Řešení:
    • nechat Claude nainstalovat závislosti v worktree,
    • nebo přidat .worktreeinclude do rootu repa (syntaxe .gitignore; kopíruje jen soubory, které matchnou pattern a jsou gitignorované).
    # .worktreeinclude
    .env
    .env.local
    config/secrets.yaml
    
    • Pozor na **/ patterny u adresářů ignorovaných jako celek — radši pojmenuj adresář v patternu (vendor/**/config.json místo **/config.json).

Cleanup a resume

  • Při exitu interactive session Claude kontroluje worktree na změny: čistý → smaže worktree i branch (named session se předtím zeptá); špinavý (změny/untracked/commity) → prompt keep/remove. Remove smaže i branch i veškerou práci v ní — neodpovídej automatikou.
  • -p (headless) cleanup nedělá — worktrees čistí až periodic sweep (dle cleanupPeriodDays) nebo ručně git worktree remove.
  • --continue / --resume vrací session zpět do jejího worktree; --fork-session zůstává v launch adresáři. Deleted worktree → session se obnoví v launch adresáři.
  • Resume z jiného worktree nebo z podadresáře worktree může selhat — resumuj z main checkoutu.

Isolation enforcement (proč to je bezpečné)

Claude Code v izolované session blokuje:

  1. File edits (Edit/Write/NotebookEdit) do main checkoutu.
  2. Commands s working directory v main checkoutu.
  3. Git redirecty (git -C, --git-dir, GIT_DIR/GIT_WORK_TREE, cd do main checkoutu).
  4. Nepřehledné commandy (dynamicky sestavené git příkazy, které nelze staticky ověřit).

Platí pro session i všechny její subagenty, interaktivně i v backgroundu. Vypnout se nedá.

Konfigurace

Setting Hodnota Význam
worktree.baseRef "fresh" (default) Branch z remote default branch (typicky origin/main)
"head" Branch z aktuálního lokálního HEAD (in-progress práce)
  • Nelze zadat konkrétní branch jménem — na to je git worktree add ručně (viz Manage worktrees manually).
  • PR checkout: claude -w "#42" nebo claude -w "https://github.com/org/repo/pull/42" (i GitLab MR URL). Worktree vznikne na .claude/worktrees/pr-42, branch z head commitu PR.
  • Opětovné použití jména: existující adresář otevře místo vytvoření nového; za jistých podmínek (čistý, na své branchi, merged PR) resetuje na default branch, jinak pokračuje od starého tipu.

Subagent isolation

  • Řekni "use worktrees for your agents" → každý subagent dostane vlastní worktree.
  • Trvale pro custom subagenta: frontmatter isolation: worktree v .claude/agents/<name>.md.
  • Subagent worktree se automaticky odstraní, když subagent skončí bez změn; se změnami zůstává, dokud ho sweep (dle cleanupPeriodDays) nemůže bezpečně smazat.
  • Během běhu agenta drží Claude Code na worktree git worktree lock, aby ho souběžný cleanup nesmazal.

Sdílené prostředí s main checkoutem

  • .git adresář (git commit z worktree funguje i se sandboxem), project-scope pluginy, uložené permission approvals (settings.local.json).

Troubleshooting (nejčastější)

  • LFS / filter drivery: git lfs install --local zapisuje filter do repo .git/config → v worktree jsou LFS pointer files místo obsahu. Fix: v worktree git lfs pull, preventivně používej globální git lfs install (bez --local).
  • Symlinky na .claude, .claude/worktrees nebo worktree path → worktree creation odmítnut (bezpečnost).
  • Refusing to use <path> as an isolation worktree → git metadata adresáře resolvovala do main checkoutu (typicky špatný .git pointer); řeš dle textu erroru.
  • includeIf v repo .git/config blokuje tvorbu worktree — přesuň nastavení přímo do configu.
  • Network path worktree (NFS/SMB) → nikdy se do něj nerresumuje.

5. Kombinace workflow: CLI + VS Code + Claude Code

Typický den s jedním repem proj:

~/src/proj                     # primary, main branch, VS Code okno A
~/src/proj-fix                 # linked worktree, fix/leak, VS Code okno B (vytvořeno GUI)
~/src/proj/.claude/worktrees/  # Claude Code sessions (feature-x, pr-42, ...)
# ráno: hotfix a feature paralelně
git -C ~/src/proj worktree add ../proj-fix -b fix/leak
code ../proj-fix                                   # VS Code okno B

# feature paralelně přes Claude Code (jiný terminál)
claude -w feature-auth

# večer: úklid
git worktree remove ../proj-fix                    # po merge do main
claude  # v interactive session exit -> cleanup prompt

Rozdělení rolí

Nástroj Kdy
CLI git worktree Plná kontrola (konkrétní branch, umístění mimo repo, bisect, srovnávání verzí)
VS Code GUI Rychlé vytvoření/otevření, diff worktree vs. workspace (Compare with Workspace), Migrate Worktree Changes
Claude Code -w Paralelní AI session bez rizika kolize editů; PR review (-w "#42")

Pravidla, na která se vyplatí držet

  1. Jeden worktree = jeden úkol = jedna branch. Nesdílej worktree mezi dvěma tasky.
  2. Merge řeš v primary checkoutu, ne v worktree — tam jen commit a push.
  3. Po skončení tasku worktree odstraň — worktrees se hromadí rychleji, než člověk čeká (git worktree list ať je pravidelný reflex).
  4. .worktreeinclude / git.worktreeIncludeFiles nastav hned u repa, kde .env/deps potřebuješ — neaž při prvním kopnutí do stěny.
  5. Venv/deps s absolutními cestami (venv, node_modules symlinkované) do worktree necopyuj — vytvoř nové.
  6. Claude Code worktree nemaž ručně, dokud session žije — drží na něm lock; sweep/exit ho uklidí sám.

6. Cvičení (udělej na play repu)

  1. git init /tmp/wt-play && cd /tmp/wt-play && echo a > f && git add . && git commit -m init
  2. git worktree add ../wt-play-fix -b fix/x — uprav f, commit v worktree; cd zpět do primary — soubor se nezměnil (sdílená historie, ne soubory).
  3. git worktree list — najdi oba.
  4. Zkus checkoutnout fix/x v primary → git odmítne (already checked out). Správná cesta: pracuj v worktree.
  5. git worktree remove ../wt-play-fix && git branch -d fix/x
  6. VS Code: vytvoř worktree přes Source Control GUI, otevři v novém okně, vyzkoušej Compare with Workspace.
  7. Claude Code (na reálném repu s trustem): claude -w test-wt, nech něco změnit, exit → sleduj cleanup prompt.