14 KiB
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
.gitadresář, 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 fetchplatí 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:
- Vedle repa (
../proj-fix,../proj-auth) — vhodné, když chceš každý worktree otevřít v jiné instanci editoru/IDE. - 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. - (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-Dpro nemergenutou). git worktree listukazuje mrtvé worktrees →git worktree prune(git je nakonec pročistí sám dlegc.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 switchjinam, nebogit 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í
.gitpřes hardlinky → dvě kopie velkého repa na disku netvoří (přesto,du -shpočítá hardlinky dřív jen jednou — na velkých repos zkontrolujdu -sh --apparent-size). git gcagit worktree prunev 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í
- Otevři Source Control view (
Ctrl+Shift+G). - Rozbal Repositories sekci (je-li skrytá, přes
...menu view). - Reprodukovatelně: klikni na repozitář →
...(More Actions) → Worktrees → Create Worktree. - Dialog: vyber branch + zadefinuj cestu (VS Code složku vytvoří a branch do ní checkoutne).
- 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 Recentpro 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
.gitfile → 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.worktreeIncludeFilesneřeší.envtypu "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-foxstyl). - Interactive mód vyžaduje workspace trust — poprvé v adresáři spusť
claudebez flagů a přijmi trust dialog, jinak--worktreespadne 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
.worktreeincludedo 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.jsonmí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 (dlecleanupPeriodDays) nebo ručněgit worktree remove.--continue/--resumevrací session zpět do jejího worktree;--fork-sessionzů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:
- File edits (
Edit/Write/NotebookEdit) do main checkoutu. - Commands s working directory v main checkoutu.
- Git redirecty (
git -C,--git-dir,GIT_DIR/GIT_WORK_TREE,cddo main checkoutu). - 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 addručně (viz Manage worktrees manually). - PR checkout:
claude -w "#42"neboclaude -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: worktreev.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
.gitadresář (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 --localzapisuje filter do repo.git/config→ v worktree jsou LFS pointer files místo obsahu. Fix: v worktreegit lfs pull, preventivně používej globálnígit lfs install(bez--local). - Symlinky na
.claude,.claude/worktreesnebo 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ý.gitpointer); řeš dle textu erroru.includeIfv repo.git/configblokuje 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
- Jeden worktree = jeden úkol = jedna branch. Nesdílej worktree mezi dvěma tasky.
- Merge řeš v primary checkoutu, ne v worktree — tam jen commit a push.
- Po skončení tasku worktree odstraň — worktrees se hromadí rychleji, než člověk čeká (
git worktree listať je pravidelný reflex). .worktreeinclude/git.worktreeIncludeFilesnastav hned u repa, kde.env/deps potřebuješ — neaž při prvním kopnutí do stěny.- Venv/deps s absolutními cestami (venv, node_modules symlinkované) do worktree necopyuj — vytvoř nové.
- 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)
git init /tmp/wt-play && cd /tmp/wt-play && echo a > f && git add . && git commit -m initgit worktree add ../wt-play-fix -b fix/x— upravf, commit v worktree;cdzpět do primary — soubor se nezměnil (sdílená historie, ne soubory).git worktree list— najdi oba.- Zkus checkoutnout
fix/xv primary → git odmítne (already checked out). Správná cesta: pracuj v worktree. git worktree remove ../wt-play-fix && git branch -d fix/x- VS Code: vytvoř worktree přes Source Control GUI, otevři v novém okně, vyzkoušej
Compare with Workspace. - Claude Code (na reálném repu s trustem):
claude -w test-wt, nech něco změnit, exit → sleduj cleanup prompt.