Scenario
Section titled “Scenario”You are deep in a feature branch. Files are half-edited, tests are half-written, nothing is
ready to commit. Someone reports a production bug that has to be fixed now, on main.
The usual answer is git stash, switch, fix, switch back, git stash pop — and hope the pop
applies cleanly. The better answer is a second working directory that shares the same repository.
Objective
Section titled “Objective”Add a worktree for a hotfix branch, commit the fix there, and return to find your feature work exactly as you left it. Along the way, discover the rule that a branch can be checked out in only one worktree at a time, and why.
Prerequisites
Section titled “Prerequisites”- Git installed
- Git worktrees explains the model; this lab exercises it
Starting state
Section titled “Starting state”mkdir -p /tmp/lab-wt && cd /tmp/lab-wtgit init -q -b main .git config user.email "lab@example.com"git config user.name "Lab User"
echo "# App" > README.mdgit add . && git commit -q -m "Initial commit"
git switch -qc feature/long-runningecho "wip" > wip.txtgit add . && git commit -q -m "WIP on long feature"echo "uncommitted" >> wip.txt
git status --shortYou are on feature/long-running with an uncommitted change:
M wip.txt-
Add a worktree for the hotfix, on a new branch from
main:Terminal window git worktree add ../lab-wt-hotfix -b hotfix maingit worktree listTwo directories, two branches, one repository.
-
Fix the bug in the new worktree:
Terminal window cd ../lab-wt-hotfixecho "fix" > hotfix.txtgit add . && git commit -q -m "Hotfix"git log --oneline -
Go back to your feature work and check nothing moved:
Terminal window cd ../lab-wtgit status --shortgit branchYour uncommitted change is still there. The
hotfixbranch exists ingit branch— it is the same repository. -
Try to break the rule. Add a second worktree for the branch you are already on:
Terminal window git worktree add ../lab-wt-dup feature/long-runningRead the error. Why does Git refuse?
-
Remove the hotfix worktree now that the fix is committed:
Terminal window git worktree remove ../lab-wt-hotfixgit worktree listgit branchThe directory is gone. Is the branch?
Validation
Section titled “Validation”After step 5, git worktree list shows only /tmp/lab-wt, git branch still lists hotfix,
and git status --short still shows M wip.txt. You handled an interruption and your work in
progress was never touched.
Step 1. -b hotfix main creates the branch at main’s tip and checks it out in the new
directory in one step. Without -b you would need an existing branch.
Step 4. A worktree is a checkout of a branch. Two checkouts of the same branch would mean two
places where git commit moves the same pointer — and two working trees that could disagree
about what the branch contains. Git forbids it.
Step 5. worktree remove deletes the directory and the worktree registration. The branch is a
ref in the shared .git; nothing about removing a checkout deletes it.
Solution
Section titled “Solution”Step 1:
Preparing worktree (new branch 'hotfix')HEAD is now at 72c0d2b Initial commit…/lab-wt 3add4f1 [feature/long-running]…/lab-wt-hotfix 72c0d2b [hotfix]Step 3 — back in lab-wt, unchanged:
M wip.txtStep 4:
Preparing worktree (checking out 'feature/long-running')fatal: 'feature/long-running' is already used by worktree at '/tmp/lab-wt'Step 5:
…/lab-wt 3add4f1 [feature/long-running]* feature/long-running hotfix mainExplanation
Section titled “Explanation”One repository, several working trees. git worktree add creates a directory with its own
HEAD, index and checked-out files, but the object database and refs live in the original .git.
A commit in either directory is immediately visible from the other, because there is only one
history.
No stash, no switch, no pop. The interruption happened in a different directory. Your editor,
your half-run tests and your uncommitted edits were never disturbed. When you came back, the state
was exactly what you left — not “what stash pop reconstructed”.
One branch, one worktree. Because each worktree has its own HEAD, two of them on the same
branch would race to move it. Git enforces the rule at worktree add time. If you genuinely need
a second copy of a branch’s content, create a new branch from it.
Removing a worktree removes a checkout, not a branch. The hotfix branch survives. Delete it
with git branch -d hotfix when it has been merged, as with any other branch.
Troubleshooting
Section titled “Troubleshooting”git worktree add says the path already exists. A previous run left the directory. Remove it
with git worktree remove --force <path> or rm -rf if it is not registered.
git worktree list shows a worktree whose directory you deleted by hand. Run
git worktree prune to clear the stale registration.
Step 4 succeeded. You are not on feature/long-running in lab-wt. Run git branch there;
the rule only bites for a branch that is currently checked out somewhere.
Clean up
Section titled “Clean up”cd /tmp && rm -rf lab-wt lab-wt-hotfix lab-wt-dupRelated lessons
Section titled “Related lessons”Next lab
Section titled “Next lab”Configure CODEOWNERS — route review requests correctly, and find the ordering mistake that silently disables every rule.