What Is Git Worktree?
git worktree is a Git command that allows you to check out multiple branches of the same repository
simultaneously into separate working directories. Each "worktree" is a full-fledged working copy with its own
staging area, index, and checked-out files, yet they all share the same underlying Git history and object database.
This means you can have, for example, one terminal working on a hotfix branch while another terminal compiles
and tests a feature branch, without needing to stash, commit, or juggle branch switches in a single directory.
Internally, Git manages these worktrees by creating additional working directories alongside the main repository
and linking them back to the shared .git directory (usually via a file called .git in the
worktree root that points to the main repository). The main working directory is the one you cloned originally,
and additional worktrees live elsewhere on your filesystem, each tied to a specific branch (or commit).
Why Git Worktree Matters
π Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →
Before worktrees, developers commonly resorted to cloning the same repository multiple times or using git stash
and constant branch switching. Worktrees solve several real-world pain points:
- Parallel tasks without context switching β Keep a long-running build, test suite, or code review active in one branch while instantly switching to another branch in a separate directory.
- Isolation of working state β Each worktree has its own set of untracked files, staged changes, and ignored files. You can experiment freely without polluting another branch's environment.
- CI/CD and automated workflows β Run integration tests on multiple branches at the same time without cloning the repo multiple times, saving disk space and network cost.
- Hotfixes and urgent changes β When an urgent bug appears, you can immediately create a worktree for the hotfix branch, fix it, and push, while your main development branch continues untouched.
- Code reviews and merges β Check out a pull request branch in a separate worktree to review or test it, then delete the worktree when done, leaving your primary environment clean.
How to Use Git Worktree
The following sections walk through a typical workflow. All examples assume a Unix-like shell (bash/zsh) and Git
version 2.20 or later, where git worktree is fully stable.
Prerequisites
Ensure you are inside a Git repository (the main working tree) when running worktree commands. The repository must
not be a bare repository (unless you explicitly use --git-dir). If you have a bare repository, you can
still create worktrees but the command syntax differs slightly.
Creating a New Worktree
To create a new worktree for an existing branch:
# From the main repository root, create a worktree for the 'feature/auth' branch
git worktree add ../project-auth feature/auth
This creates a directory project-auth at the same level as your current repository, checks out the branch
feature/auth, and links it to the main repository. If the branch doesn't exist yet and you want to create
a new branch at the same time, use the -b flag:
git worktree add -b hotfix/critical-bug ../project-hotfix main
This creates a new branch hotfix/critical-bug starting from main and checks it out in the
../project-hotfix directory. You can also base the new branch on a specific commit instead of a branch name:
git worktree add -b experiment/sql-opt ../project-experiment a1b2c3d
Listing Existing Worktrees
To see all worktrees linked to the current repository, including the main worktree:
git worktree list
Output looks like:
/home/user/projects/main-repo abc123 [main]
/home/user/projects/project-auth def456 [feature/auth]
/home/user/projects/project-hotfix ghi789 [hotfix/critical-bug]
The first column is the working directory path, the second column is the current HEAD commit hash, and the third shows the checked-out branch (if any). The main worktree is always listed first.
Switching Between Worktrees
There is no special command to "switch" β you simply change directory into the worktree's root. From there, all normal Git commands operate on that worktree's branch and state. For example:
cd ../project-hotfix
# Now you are in the hotfix branch environment
git status
git add .
git commit -m "Fix critical bug"
git push origin hotfix/critical-bug
Working with Branches Across Worktrees
Each worktree has a checked-out branch that cannot be checked out elsewhere simultaneously. If you try to check out
a branch that is already checked out in another worktree, Git will refuse (unless you force with --force,
but thatβs dangerous). This prevents conflicting modifications.
To change the branch in an existing worktree, navigate to that worktree and use git switch or
git checkout as usual. For example, to switch the project-auth worktree from
feature/auth to feature/auth-v2:
cd ../project-auth
git switch feature/auth-v2
You can also use git worktree add to create a new worktree from any commit or tag, resulting in a
detached HEAD state, which we'll cover shortly.
Removing a Worktree
When you're done with a worktree, cleanly remove it to avoid stale entries. First, ensure you have committed or discarded any changes inside that worktree. Then, from the main repository (or any worktree), run:
git worktree remove ../project-auth
This deletes the directory project-auth (if it's empty of untracked/ignored files that Git cares about)
and removes the worktree entry from Git's metadata. If the directory contains untracked files that you want to keep,
you can either move them first, or use --force (but that will delete them).
Alternatively, you can manually delete the directory and then run git worktree prune to clean up
stale records:
rm -rf ../project-auth
git worktree prune
The prune command removes worktree references for directories that no longer exist. Itβs safe to run
periodically to clean up after manual deletions.
Advanced: Worktree with Detached HEAD
Worktrees are excellent for building or testing specific commits without creating a branch. To check out a particular commit, tag, or ref in detached HEAD mode:
git worktree add ../project-release v2.1.0
This creates a worktree at ../project-release with HEAD pointing to the tag v2.1.0. You can
inspect, build, or run tests there. If you later decide to start a branch from this point, simply enter the worktree
and create a branch:
cd ../project-release
git switch -c release/v2.1.0-hotfix
Handling Submodules
Worktrees and submodules can coexist, but require attention. When you create a new worktree, Git does not automatically clone or populate submodules for that worktree. You must initialize and update them inside the new worktree:
cd ../project-auth
git submodule update --init --recursive
Each worktree maintains its own submodule checkout state. This allows different worktrees to have different submodule versions if needed, but it also means you must update submodules separately in each worktree when required.
Best Practices
-
Use meaningful directory names β Name worktree directories after the branch or purpose, e.g.,
../project-hotfix-login, to instantly identify them. -
Keep worktrees outside the main repository folder β The typical pattern is to place them as
siblings of the main repo (
../project-<branch>). Avoid nesting a worktree inside another worktree or the main working tree. - Commit or stash before removing β Always ensure the worktree is clean before removal, or consciously discard changes, to prevent accidental data loss.
-
Run
git worktree listregularly β It gives a clear overview of active worktrees and their branches, helping you remember whatβs still around. -
Use
git worktree pruneafter manual cleanup β If you delete directories manually, prune cleans the stale records. Consider adding it to a periodic maintenance alias. -
Beware of hooks and scripts β Git hooks (like
post-checkout) run in each worktree independently. Test hooks to ensure they work correctly when multiple worktrees exist. -
Don't share environment-specific artifacts β Since worktrees share the same repository history,
they also share things like reflogs and the object database. However, each has its own
.gitfile pointing back to the main repo, so don't copy a worktree directory to another machine; it won't work.
Common Pitfalls and How to Avoid Them
-
"Branch already checked out" error β If you attempt to check out a branch that is already active
in another worktree, Git blocks it. Use
git worktree listto identify which worktree holds that branch, then either finish work there or use a different branch. -
Forgetting to update submodules β After creating a worktree, submodule directories exist but
are empty. Run
git submodule update --init --recursivebefore building. - Disk space concerns β Worktrees share Git history, so they add only the working directory files (the checked-out snapshot) plus a tiny metadata overhead. They are far lighter than full clones. Nevertheless, many large worktrees can still consume noticeable space due to node_modules, built artifacts, etc. Clean those per worktree as needed.
-
Deleting the main worktree β You cannot remove the main worktree with
git worktree remove(the original directory). You can delete it manually, but that effectively removes the whole repository, including all other worktrees, because they depend on it. Avoid this unless you intend to delete the entire project. -
Network drives and symlinks β Worktrees rely on a
.gitfile that points to the main repository. This can break if the main repository moves. Keep paths stable.
Conclusion
Git worktrees transform the way you handle multiple branches, turning a single repository into a lightweight
multitasking environment. Instead of cloning repeatedly or constantly stashing and switching, you can maintain
several active checkouts side by side. The workflow is straightforward: add a worktree, cd into it, work as
usual, and remove when done. With attention to submodules, clean removal, and a habit of listing worktrees,
you'll avoid surprises. Whether you're juggling hotfixes, long-running feature branches, or CI pipelines,
git worktree is an indispensable tool that keeps your development fast and organized.