Master Git Worktrees: Seamlessly Manage Multiple Branches Without Cloning
This guide explains why traditional stash or multiple‑repo cloning fall short, introduces Git's worktree feature, and walks through adding, listing, removing, and pruning worktrees so developers can handle hotfixes and features in parallel without disrupting their main workflow.
Background
As programmers we often have to switch between feature development and urgent hotfixes, and the usual solutions are either committing unfinished work or using git stash | git stash pop. The stash approach has limitations in several scenarios.
Scenarios We Face
Running long tests on the main branch; switching to a hotfix or feature interrupts testing.
Large projects make frequent index switching costly.
Older releases have different settings, causing IDE re‑structure overhead.
Branch switching requires resetting environment variables (dev/qa/prod).
Need to switch to a colleague’s code to reproduce bugs.
Why Not Clone Multiple Repos?
State synchronization between repos is difficult; cherry‑picking across repos is cumbersome.
Each repo repeats the full .git history, consuming large disk space.
Managing many repositories for a single project is error‑prone.
git‑worktree
Git has supported worktrees since 2015, but many developers are unaware of it. It allows a single repository to have multiple working directories that can be on different branches without interfering with each other.
Maintain one repo while working on several branches simultaneously, without interference.
Common commands (most frequently used):
git worktree add [-f] [--detach] [--checkout] [--lock] [-b <new-branch>] <path> [<commit-ish>]
git worktree list [--porcelain]
git worktree remove [-f] <worktree>
git worktree prune [-n] [-v] [--expire <expire>]Two Git Knowledge Points You Might Miss
When you run git init or git clone, the repository initially has only one worktree, called the main worktree.
In a working directory Git either has a .git directory or a .git file that points to the actual .git folder.
git worktree add
Assume the project root is amend-crash-demo:
.
└── amend-crash-demo
1 directoryRun the following commands:
cd amend-crash-demo
git worktree add ../feature/feature2Output:
➜ amend-crash-demo git:(main) git worktree add ../feature/feature2
Preparing worktree (new branch 'feature2')
HEAD is now at 82b8711 add main fileDirectory structure becomes:
.
├── amend-crash-demo
└── feature
└── feature2
3 directoriesThe command creates a new branch feature2 at the current HEAD and places its working tree at the specified path.
Inside the new worktree there is a .git file that points back to the main repository:
gitdir: /Users/rgyb/Documents/projects/amend-crash-demo/.git/worktrees/feature2Now you can work on feature2 (add/commit/pull/push) without affecting the main worktree.
If your branch naming convention includes a slash (e.g., feature/JIRAID-Title), the slash would be interpreted as a directory separator. Use the -b option to create the branch while keeping the desired name:
git worktree add -b "hotfix/JIRA234-fix-naming" ../hotfix/JIRA234-fix-namingResulting directory layout:
.
├── amend-crash-demo
├── feature
│ └── feature2
└── hotfix
└── hotfix
└── JIRA234-fix-naming
6 directoriesAfter adding the -b flag, the structure is tidy:
.
├── amend-crash-demo
├── feature
│ └── feature2
└── hotfix
├── JIRA234-fix-naming
└── hotfix
└── JIRA234-fix-naming
7 directoriesgit worktree list
From any worktree you can list all existing worktrees:
git worktree listExample output shows the main worktree and the additional ones:
/Users/rgyb/Documents/projects/amend-crash-demo 82b8711 [main]
/Users/rgyb/Documents/projects/chore/chore 8782898 (detached HEAD)
/Users/rgyb/Documents/projects/feature/feature2 82b8711 [feature2]
/Users/rgyb/Documents/projects/hotfix/hotfix/JIRA234-fix-naming 82b8711 [JIRA234-fix-naming]
/Users/rgyb/Documents/projects/hotfix/JIRA234-fix-naming 82b8711 [hotfix/JIRA234-fix-naming]git worktree remove
Remove a worktree by name:
git worktree remove hotfix/hotfix/JIRA234-fix-namingIf the worktree has uncommitted changes, force removal with -f:
git worktree remove -f hotfix/JIRA234-fix-naminggit worktree prune
Use git worktree prune as a cleanup fallback to delete stale administrative files left after worktree removal.
Summary
The complete workflow consists of four commands:
git worktree add
git worktree list
git worktree remove
git worktree pruneUsing a single repository with multiple worktrees avoids the drawbacks of cloning many repos and keeps the workflow smooth.
My practice: I keep all feature worktrees under a feature directory and all hotfix worktrees under a hotfix directory to maintain a tidy disk layout.
Soul Questions
Can the main worktree be deleted? Why?
Do you understand how the .git/worktrees directory changes when repeatedly creating and deleting worktrees?
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
