Skip to content

Lab: Parallel Work with Git Worktrees

Lesson 3 of 4Intermediate3 min readHands-On Git & GitHub Labs · Workflow Labs
Time15 minutes
LevelIntermediate
You needLocal Git only — no GitHub account needed

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.

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.

  • Git installed
  • Git worktrees explains the model; this lab exercises it
Terminal window
mkdir -p /tmp/lab-wt && cd /tmp/lab-wt
git init -q -b main .
git config user.email "lab@example.com"
git config user.name "Lab User"
echo "# App" > README.md
git add . && git commit -q -m "Initial commit"
git switch -qc feature/long-running
echo "wip" > wip.txt
git add . && git commit -q -m "WIP on long feature"
echo "uncommitted" >> wip.txt
git status --short

You are on feature/long-running with an uncommitted change:

M wip.txt
  1. Add a worktree for the hotfix, on a new branch from main:

    Terminal window
    git worktree add ../lab-wt-hotfix -b hotfix main
    git worktree list

    Two directories, two branches, one repository.

  2. Fix the bug in the new worktree:

    Terminal window
    cd ../lab-wt-hotfix
    echo "fix" > hotfix.txt
    git add . && git commit -q -m "Hotfix"
    git log --oneline
  3. Go back to your feature work and check nothing moved:

    Terminal window
    cd ../lab-wt
    git status --short
    git branch

    Your uncommitted change is still there. The hotfix branch exists in git branch — it is the same repository.

  4. 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-running

    Read the error. Why does Git refuse?

  5. Remove the hotfix worktree now that the fix is committed:

    Terminal window
    git worktree remove ../lab-wt-hotfix
    git worktree list
    git branch

    The directory is gone. Is the branch?

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.

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.txt

Step 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
main

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.

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.

Terminal window
cd /tmp && rm -rf lab-wt lab-wt-hotfix lab-wt-dup

Configure CODEOWNERS — route review requests correctly, and find the ordering mistake that silently disables every rule.

Choose a learning pathA sequenced route through the curriculum for wherever you are now.