How to Use Git Worktree for Parallel Branch Development
Problem
I was working on a feature branch, and everything was going well. Then my manager asked me to fix a critical bug on the main branch immediately.
The problem? My feature branch had half-done changes. I did not want to commit incomplete code. I also did not want to lose my work.
I tried stashing:
git stashBut I kept forgetting about my stashed changes. Sometimes I created multiple stashes and lost track of them.
I tried committing with a temporary message:
git add .git commit -m "WIP: feature in progress"But this polluted my commit history. I had to amend or squash later. It was messy.
There had to be a better way.
Environment
- Git version: 2.43.0
- Operating System: macOS Sonoma
- Repository: A monorepo with multiple features in development
What happened?
I was in the middle of developing a new feature on a branch called feat/user-authentication. I had modified several files but the feature was not complete. The tests were failing.
Then I received a bug report. The bug was on the main branch and needed immediate attention.
I ran:
git checkout mainGit refused:
error: Your local changes to the following files would be overwritten by checkout: src/auth/login.ts src/auth/register.tsPlease commit your changes or stash them before you switch branches.AbortingI had to choose between:
- Stashing (and risking forgetting about it)
- Committing incomplete work (messy history)
- Copying files to a backup folder manually (error-prone)
None of these options felt right. I asked a senior developer, and they introduced me to Git worktree.
How to solve it?
Git worktree lets you checkout multiple branches into separate directories from a single repository. You can have multiple working directories, each with a different branch, without cloning the repository multiple times.
Step 1: Create a worktree
I created a new worktree for the bug fix:
git worktree add ../bugfix-login mainThis created a new directory called bugfix-login at the same level as my main repository. The new worktree was already on the main branch.
Output:
Preparing worktree (checking out 'main')HEAD is now at a1b2c3d Fix navigation bugStep 2: List all worktrees
To see all my worktrees:
git worktree listOutput:
/Users/zhaocaiwen/projects/myapp a1b2c3d [main]/Users/zhaocaiwen/projects/bugfix-login a1b2c3d [main]Wait, both showed the same branch. I needed to create a new branch for my bug fix:
git worktree add ../bugfix-login -b fix/login-redirect mainOutput:
Preparing worktree (new branch 'fix/login-redirect')HEAD is now at a1b2c3d Fix navigation bugNow I could work on the bug fix in the bugfix-login directory while my original feature work remained untouched in the main repository.
Step 3: Work in the new worktree
I navigated to the new worktree:
cd ../bugfix-loginNow I could make changes, run tests, and commit as usual. My original work in the main repository was still there, waiting for me to return.
After fixing the bug:
git add .git commit -m "Fix login redirect issue"git push origin fix/login-redirectStep 4: Remove the worktree
After merging the fix, I removed the worktree:
git worktree remove ../bugfix-loginOr from within the worktree:
cd /Users/zhaocaiwen/projects/myappgit worktree remove bugfix-loginQuick reference
Here are the most common commands:
# Create a worktree with an existing branchgit worktree add <path> <branch>
# Create a worktree with a new branchgit worktree add <path> -b <new-branch> <base-branch>
# List all worktreesgit worktree list
# Remove a worktreegit worktree remove <path>
# Prune stale worktree informationgit worktree pruneReason
Why does Git worktree work this way?
Traditional Git has one working directory per repository. When you switch branches, Git replaces the files in your working directory with the files from the new branch. This is why uncommitted changes cause problems.
Git worktree solves this by creating additional working directories. Each worktree has its own working directory but shares the same .git directory (actually, it creates a .git file that points to the main repository’s .git directory).
Benefits:
- No need to stash: Your uncommitted changes stay in their original worktree.
- No duplicate cloning: Worktrees share the Git history, so you save disk space.
- Faster context switching: No need to wait for Git to swap files in and out.
- Parallel development: You can have multiple terminals open, each on a different branch.
Summary
In this post, I showed how Git worktree solves the problem of working on multiple branches simultaneously. Instead of stashing, committing incomplete work, or cloning repositories multiple times, you can use worktrees to have multiple working directories from a single repository.
The key commands are:
git worktree addto create a new worktreegit worktree listto see all worktreesgit worktree removeto clean up
Next time you need to context-switch between branches, try worktree. Your uncommitted changes will thank you.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments