You’re mid-feature when PM says prod is on fire. The reflex move: git stash, check out master, fix, come back, stash pop. But then the dev server restarts, the IDE re-indexes, and stash silently ate your untracked build artifacts.
git worktree fixes this cleanly: one repo, many checked-out branches in separate directories, each with its own HEAD, index, and untracked files β all sharing the same object database. The feature stays exactly where you left it; the hotfix happens next door.
vs stash, vs multiple clones
| Approach | Switch cost | Disk | Object sync |
|---|---|---|---|
git stash + checkout | High (dev server restarts, IDE reindex) | Cheap | Single repo |
| Multiple clones | Low | Wasteful (GBs on large repos) | Each fetches separately |
git worktree | Low | Cheap (shared objects) | One fetch updates all |
Worktree is the synthesis β filesystem isolation with a unified object store.
Core Commands
| |
Short aliases make it muscle memory:
| |
Real Workflows
1. Hotfix without disturbing feature work
| |
The feature’s dev server never stopped. node_modules untouched. IDE didn’t re-index.
2. Long test run + keep coding
pytest / cargo test takes 10 minutes. Open a worktree to run it there while you keep editing the next commit. Zero interference.
| |
3. Code review without polluting your state
| |
4. Multiple AI agents in parallel (the most underrated 2025 use case)
Claude Code / Cursor / Aider only work in one directory at a time β running two in the same folder means they overwrite each other’s files. One branch per worktree and you can run three agents on three features simultaneously, each with its own dev server port and node_modules, no collisions:
| |
Claude Code’s Agent tool even has a built-in isolation: "worktree" option β sub-agents automatically run in a worktree and merge back when done.
Three Directory Layouts
Sibling dirs (simplest)
| |
Plays well with editors’ “one folder, one project” mental model.
.worktrees/ subdir
| |
Everything co-located. Add .worktrees/ to global gitignore. Downside: some tools (ESLint, tsc) recurse into it.
Bare repo pattern (best for heavy multi-branch work)
| |
Result:
| |
No “primary working copy” β every branch is a worktree, cd is the branch switch. Pairs beautifully with tmux and AI agents.
Gotchas
.git in a linked worktree is a file, not a directory. Contents are gitdir: /path/to/main/.git/worktrees/<name>. Tools that read .git/ as a directory will break.
You can’t check out the same branch in two worktrees. By design β prevents index divergence. Override with --force or use detached HEAD.
Submodules are painful. worktree move refuses; remove needs --force. .git/modules/ is shared, so switching submodule commits in one worktree affects the others. Heavy-submodule repos need care.
node_modules, venv, target/ are per-worktree. Disk gets hungry. Mitigations:
- pnpm’s content-addressable store β reinstalling across worktrees uses almost no extra space
- Rust:
CARGO_TARGET_DIR=~/.cache/cargo-targetshares target dirs - uv, poetry caches are shareable too
.env doesn’t get copied. Use direnv β drop a .envrc in each worktree and it auto-loads on cd.
Hooks are shared (.git/hooks/ is in the common dir). If a hook assumes repo root via a hardcoded path, it breaks in linked worktrees. Always use git rev-parse --show-toplevel for the current worktree’s root.
IDE indexes run per worktree. VS Code / JetBrains index each one independently β duplicate CPU and disk. Structural limit, no way around it.
Editor Integration
VS Code: use multi-root workspace (File β Add Folder to Workspace) to open multiple worktrees at once, or just open each in its own window. Since 2024, GitHub.vscode-pull-request-github checks out PRs as worktrees.
JetBrains: native worktree UI in the Git tool window since 2023.2 β create, switch, remove from the GUI.
fzf quick-switch:
| |
Type wtcd, fuzzy-search worktree paths, enter to cd.
What’s New in 2024β2026
Git 2.44 (2024/2): git worktree add --orphan β creates a worktree with an unborn branch. Handy for gh-pages-style split deploy branches.
Git 2.46 (2024/7): worktree.useRelativePaths config + --relative-paths flag β internal links use relative paths. The main repo (or the whole dir tree) can move without breaking worktrees. Huge for Dropbox/iCloud sync and containerized dev.
Git 2.48 (2025/1): git worktree repair auto-fixes absolute/relative path mismatches.
Git 2.50 (mid-2025): relative paths and porcelain output have stabilized.
Ecosystem: “one worktree per AI agent branch” went mainstream in 2025. git-town, ghq, and the gh CLI all picked up first-class worktree support.
Getting Started
- In any repo, try
git worktree add ../test-wt -b test-branchand poke around - Back in the main worktree, notice
git branchsees it butgit statusis untouched git worktree remove ../test-wtβ main worktree is completely unchanged- Add
wta/wtl/wtraliases, build muscle memory - Next hotfix, use worktree instead of stash β feel the difference
For anyone using AI coding agents, worktree isn’t a bonus β it’s required. The “only one agent per repo” limitation is the exact thing worktree removes.
