Git-Mastery: Lessons

T6L6. Working on Multiple Branches with Worktrees


Git worktrees let one local repository have multiple working directories at the same time.

This lesson covers that part.

At times, you need to have more than one branch checked out simultaneously. For example, while tests are running on your feature branch, you might need to quickly fix an urgent bug in another branch. Switching branches alters files in the project directory that the running tests might depend on. Another modern use case is coordinating multiple AI agents to work on different tasks in parallel, with each agent working on its own branch.

Git's worktree feature lets you create additional working directories attached to the same local repository. This lets you keep different branches active in separate directories. Unlike copying the repo or cloning it again, worktrees are lightweight and share the same underlying repository data, which makes it easier to bring changes from one worktree to another.

SIDEBAR: Working Directory vs Working Tree vs Worktree

  • A working directory is the folder on your computer that contains your repo files. This is a filesystem idea: it is the directory you see in your editor, terminal, or file explorer. In a regular Git repository, the hidden .git directory is stored inside the top-level working directory and contains Git’s repository metadata .
  • A working tree is Git’s view of the checked-out project files in the working directory, excluding Git’s own metadata. When Git reports modified, deleted, or untracked files, it is inspecting the working tree and comparing it with the staging area and HEAD.
  • A worktree is a working directory managed by Git's worktree feature.

The terms overlap, but they emphasize different perspectives: filesystem location, Git’s model of checked-out files, and Git’s feature for managing linked working directories.

The three terms are often used interchangeably, though, and the context usually makes it clear which one is meant.

Normally, a local repository starts with one worktree checked out in one working directory. When you switch branches, Git updates the files in that working directory so that they match the branch you switched to.

A linked worktree is an additional checkout that is connected to the same local repository and has its own working directory, staging area, and current HEAD, while sharing the same underlying repository data. Implications:

  1. Each worktree can be on a different branch, because each has its own HEAD.
  2. Changes made in one worktree do not appear as uncommitted changes in other worktrees, because each worktree has its own checked-out files.
  3. Commits and branch refs updated in one worktree are immediately visible in commands such as git log --all from other worktrees, but each worktree’s checked-out files remain separate.

Git generally allows a branch to be checked out in only one worktree at a time. This prevents two worktrees from trying to move the same branch ref independently. In practice, you usually give each active worktree its own branch, or use a worktree temporarily to inspect a specific point in history.

HANDS-ON: Work with multiple worktrees

Preparation

Create a study-notes repo as follows:

mkdir study-notes
cd study-notes
git init -b main
echo "# Study Notes" > README.md
git add README.md
git commit -m "Add README"

1 Add a linked worktree for a science branch. The git worktree add -b <branch> <path> command creates a new branch and checks it out in a new directory.

git worktree add -b science ../study-notes-science

In this case, Git creates the science branch in the ../study-notes-science directory.

A worktree can be located anywhere in the filesystem. One common convention is to create it in the same parent directory as the original working directory and name it <project name>-<branch name>, as shown above.

2 List the worktrees attached to the repo.

git worktree list
/.../study-notes            7947b49 [main]
/.../study-notes-science    7947b49 [science]

The output should show two worktrees: the original worktree and the linked science worktree.

3.1 Switch to the new worktree. To switch to a worktree, navigate to the directory where it is located.

cd ../study-notes-science

3.2 Do some work in the new worktree.

echo "# Science Notes" > science.md
git add science.md
git commit -m "Add science.md"
echo "Revise for science test" >> science.md
git status --short

These commands should create a new commit and leave some uncommitted changes in this worktree.

4.1 Switch back to the original worktree. Check the state.

cd ../study-notes
git log --oneline --decorate --graph --all
git status --short
 * 54a709f (science) Add science.md
 * 1587164 (HEAD -> main) Add README

The empty git status --short output shows that the uncommitted changes in the science worktree do not appear in the original worktree. The new commit you added in the science worktree appears in the git log output because the commit history is shared between worktrees.

4.2 Do some work in the original worktree.

echo -e "This is for keeping study notes" >> README.md
git commit -am "Add more info to README"

5 Switch back to the science worktree. Check the state.

cd ../study-notes-science
git status --short
git log --oneline --decorate --graph --all

Observe that the uncommitted changes you made earlier are still there. You can also see the new commit you made in the original worktree. This shows that the revision history is visible across linked worktrees.

6 Switch back to the original worktree. Attempt to remove the science worktree.

cd ../study-notes
git worktree remove ../study-notes-science
fatal: '../study-notes-science' contains modified or untracked files, use --force to delete it

Git refuses to remove the science worktree because it has uncommitted changes. This protects unsaved work from accidental deletion.

7 Go back to the science worktree. Commit the changes. Try to switch to main.

cd ../study-notes-science
git commit -am "Add more info to science.md"

While you are in the science worktree, first try to switch to main so that you can merge the science branch into it.

git switch main
fatal: 'main' is already used by worktree at '..../study-notes'

Git refuses to switch to main because it is already checked out in the original worktree.

8 Go back to the original worktree. Merge the science branch from there.

cd ../study-notes
git merge science

The merge should now succeed. Although the science branch was created in the science worktree, it can still be merged from another worktree.

9 Now you can remove the science worktree.

git worktree remove ../study-notes-science

Run git worktree list one last time. You should see only the original study-notes worktree.

git worktree list

Observe that the science branch is still there (e.g., run git branch --list) even though the worktree we created for it has been removed. You can delete the branch separately (e.g., run git branch -d science) if you wish.

If you delete a linked worktree folder manually instead of using git worktree remove, Git may keep a stale entry until you run git worktree prune.

done!