How do you use Git worktrees to work on multiple branches simultaneously without stashing or cloning?
Quick Answer
git worktree add creates additional working directories linked to the same repository, each checked out to a different branch. This lets you work on a hotfix, review a PR, and continue feature development simultaneously without stashing, cloning, or switching branches. All worktrees share the same .git object store and refs.
Detailed Answer
Think of git worktree like having multiple desks in your office, each with a different project spread out on it. Without worktrees, you have one desk and must clear it completely (stash or commit) every time you switch to a different project. With worktrees, you walk to a different desk where that project is already laid out, do your work, and walk back. All desks share the same filing cabinet (the .git directory), so commits made at any desk are visible from all others.
Git worktree, introduced in Git 2.5, allows you to create additional working directories that are all linked to the same repository. Each worktree is checked out to a different branch, and you cannot have two worktrees on the same branch simultaneously. The main working directory (where you originally cloned) is the main worktree, and additional worktrees are created with git worktree add <path> <branch>. All worktrees share the same .git directory, object store, refs, and configuration, which means they share the same branches, tags, remotes, and history without any duplication.
Internally, worktrees are tracked in .git/worktrees/<name>/, which contains a gitdir file pointing back to the main .git directory, a HEAD file tracking the checked-out branch, and an index file for the worktree's staging area. The main repository's .git directory contains a worktrees/ directory listing all linked worktrees. Because all worktrees share the same refs, a commit made in one worktree immediately updates the branch pointer visible to all other worktrees. The constraint that two worktrees cannot share a branch is enforced to prevent confusion about which working directory's changes should be reflected in the branch. Locked worktrees (git worktree lock) prevent automatic pruning when the path is temporarily unavailable, such as on a removable drive.
In production workflows, worktrees solve the constant context-switching problem. A senior engineer's typical day might involve: developing feature/checkout-redesign, getting pulled into reviewing a colleague's PR on feature/payment-retry, and suddenly needing to fix a production bug on hotfix/cve-2025-1234. Without worktrees, each context switch requires stashing or committing WIP, switching branches, and rebuilding node_modules or recompiling. With worktrees, you set up three directories: ~/repos/payments-api (main development), ~/repos/payments-api-review (PR reviews), and ~/repos/payments-api-hotfix (urgent fixes). Each has its own working directory, index, and node_modules, so switching context is just switching terminal tabs. This is especially valuable for projects with slow build steps or complex local environments.
A critical gotcha: each worktree has its own working directory and index but shares the same object store. This means git gc, git fetch, and git remote operations affect all worktrees simultaneously. Another trap: forgetting to remove worktrees when done. Orphaned worktree directories waste disk space and can cause confusion. Use git worktree list to audit and git worktree remove to clean up. Also, IDE integrations can behave unexpectedly with worktrees because some tools assume a single working directory per repository. VS Code handles worktrees well by opening each worktree as a separate window, but other editors may need configuration. Finally, worktrees do not duplicate node_modules, venv, or other dependency directories, so each worktree needs its own dependency installation.