The problem worktrees solve
You are deep in a feature branch when an urgent bug report lands. Stash, switch, fix, switch back, pop the stash - context lost, half a coffee gone. Worktrees let you check out multiple branches simultaneously, in different directories, sharing the same .git.
Adding a worktree
# Create a new directory with a branch checked out
git worktree add ../hotfix-1234 hotfix/login-redirect
# Or create a new branch on the fly
git worktree add -b hotfix/login-redirect ../hotfix-1234 main
You now have a full working tree at ../hotfix-1234. Your original directory is unaffected; you can run tools in both simultaneously.
Listing and managing
git worktree list
# /path/to/main deadbeef [main]
# /path/to/hotfix-1234 cafef00d [hotfix/login-redirect]
git worktree remove ../hotfix-1234
git worktree prune # clean up dangling worktree records
How it works under the hood
The .git in your original directory is the actual repo. Each additional worktree has a .git file (not a directory) pointing to main-repo/.git/worktrees/<name>. Branches are still shared - one branch can be checked out in only one worktree at a time.
Concrete workflows
Hotfix without disturbing your work
git worktree add ../hotfix main
cd ../hotfix
git checkout -b hotfix/cve-fix
# ...fix, push, PR, merge...
cd -
git worktree remove ../hotfix
Long-running compare
git worktree add ../old v2.4.0
diff -ru ../old/src ./src
Reviewing a colleague's PR locally
gh pr checkout 123 --branch pr-123
git worktree add ../pr-123 pr-123
cd ../pr-123
npm test
CI and worktrees
Worktrees can speed up CI when multiple jobs share a clone:
git worktree add ./build-linux $SHA
git worktree add ./build-windows $SHA
# Run platform builds in parallel
Limitations
- You cannot check out the same branch in two worktrees - clone or use detached HEAD.
- Some hooks may misbehave if they assume one working tree.
- Submodules in worktrees can have surprising behaviour - test before relying on it.
The mental model
Picture worktrees as multiple "checkouts" sharing one object database. The shared database means cheap creation - no second clone, no duplicated objects. The independent working trees mean you can run tests, builds, and editors without interference.
Aliases that help
[alias]
wt = worktree
wtl = worktree list
wta = worktree add
wtr = worktree remove
Once you internalise worktrees, stashing and branch-switching feel primitive. The five-minute setup repays itself the first time a hotfix lands while you are mid-feature.