π Read this trending post from Hacker News π
π **Category**:
β **What Youβll Learn**:
Approx ~10 minutes reading time for 1,916 words.
Introduction
Recently whilst tinkering with a particularly tricky project, I came across Gitβs worktree feature. A tool that lets you work on multiple branches simultaneously, each in its own directory, all sharing the same underlying repository history.
Simple visualisation;
~/Herd/
βββ my-project/ # main worktree, branch `main`
β βββ .git/ # main git directory
βββ my-project-feature/ # linked worktree, branch `feature/login-form`
βββ my-project-hotfix/ # linked worktree, branch `hotfix/payment-bug`
All the directories above share the same commit history and are linked to the same .git object database even though each has its own working directory state.
Each directory behaves like a normal checkout, you edit files, commit and push as usual, but you avoid constantly hopping branches in a single working tree.
The difference between Git branch and worktree
Traditionally, working on multiple branches meant a lot of git checkout and git stash constantly saving your place, switching context and hoping you didnβt lose anything important. Itβs easy to get lost, especially when a production bug interrupts your flow. With git worktree you can add a new working directory for any branch (existing or new) and keep your workstreams separate. For example;
# Add an existing branch as a worktree
git worktree add ../my-project-feature feature-branch
# Or create a new branch and worktree in one go
git worktree add -b new-feature ../my-project-new-feature
This creates new directories at the same level as your main project, checked out to the branches you specify. You can now edit files, commit and push in each directory independently without touching your main working directory.
Hereβs how your setup might look;
my-project/ # main worktree, branch `main`
my-project-feature/ # worktree for `feature-branch`
my-project-new-feature/ # worktree for `new-feature`
One important limitationΒ is that the same branch cannot be checked out in more than one worktree at the same time. Each worktree must have a unique branch checked out. In practice, that encourages a tidy mapping of βone task, one branch, one directoryβ, which makes it easier to stay oriented mentally.
Practical example, juggling a feature and a hotfix
Hereβs a realistic scenario, youβre working on a checkout feature when a production bug appears.
Initial layout;
~/Herd/
βββ shop/ # main worktree, branch `main`
βββ .git/
Create a feature worktree;
cd ~/Herd/shop
git worktree add -b feature/checkout ../shop-checkout
New layout;
~/Herd/
βββ shop/ # main worktree, branch `main`
β βββ .git/
βββ shop-checkout/ # linked worktree, branch `feature/checkout`
You can easily develop the checkout feature in shop-checkout while keeping shop on main for quick reviews.
A production bug appears, create a hotfix worktree
cd ~/Herd/shop
git worktree add -b hotfix/payment-fail ../shop-payment-hotfix
Your layout becomes;
~/Herd/
βββ shop/ # main worktree, branch `main`
βββ shop-checkout/ # feature worktree, `feature/checkout`
βββ shop-payment-hotfix/ # hotfix worktree, `hotfix/payment-fail`
At this point you can;
- Fix and test the production bug in the
shop-payment-hotfixworktree. - Continue to iterate on
feature/checkoutin theshop-checkoutworktree. - Keep
shopfree onmainfor merges and any code reviews.
How to merge a worktree into another branch
Merging changes from a worktree branch is just like any other Git merge, but the context is clearer because each branch lives in its own directory. Hereβs a typical workflow for merging the feature branch into main;
- Finish your work in the feature worktree and commit your changes.
- Switch to your main worktree directory;
cd ../my-project && git checkout main
- Merge the feature branch;
git merge feature-branch
- Resolve any conflicts, then push.
Because each worktree is dedicated to a single branch, itβs much harder to accidentally commit to the wrong branch or lose your place when a hotfix interrupts your feature workβ¦ anyway, thatβs the theory. π
Inspecting your current worktrees
Before you start removing or pruning anything, it helps to see what worktrees Git currently knows about;
git worktree list
Example output;
/Users/barrd/Herd/shop 66c16256 [main]
/Users/barrd/Herd/shop-checkout 0c8ba118 [feature/checkout]
/Users/barrd/Herd/shop-payment-hotfix a16e4be2 [hotfix/payment-fail]
You can mentally map this to something like;
[main] β /home/user/Herd/shop
[feature/checkout] β /home/user/Herd/shop-checkout
[hotfix/payment-fail] β /home/user/Herd/shop-payment-hotfix
Itβs now obvious which branches are checked out and where thus helping to avoid trying to reuse a branch that is already attached to another worktree.
How to remove a worktree
Once youβre done with a worktree, itβs good practice to tidy up. To do so safely, after committing or stashing any changes;
git worktree remove ../my-project-feature
This only works on clean worktrees (no uncommitted changes or untracked files) unless you pass --force and it cannot remove the main worktree.
Remember
Removing a worktree only deletes the working directory, it does not delete the branch itself. Always check with git status in that worktree before removing to avoid losing uncommitted work.
Cleaning up stale worktrees with prune
If youβve deleted a worktree directory manually, Git still keeps metadata for it under the main repositories worktrees directory. In that case, git worktree list will show entries marked as missing.
You can clean up those stale entries with;
git worktree prune
To only prune entries that have been unused for some time, you can add an expiry;
git worktree prune --expire 7.days.ago
Using --expire now removes all stale worktree metadata immediately, which can be handy in a local development environment where you frequently nuke old unneeded directories.
Final thoughts
Itβs been around since v2.5, which was ~10 years ago and Iβd never used itβ¦ But itβs now transformed my workflow, especially when juggling parallel features and urgent hotfixes. It keeps all the elements compartmentalised, reduces context switching and means stashing has become a rare exception.
For simple, sequential work, traditional branching is still the way to go but if you ever find yourself wishing you could be in two places at once, give git worktree a try.
If youβve any favourite workflow variations you take advantage of please get in touch and let me know.
Article Information
β‘ **Whatβs your take?**
Share your thoughts in the comments below!
#οΈβ£ **#Parallel #development #headaches #Git #worktree #barrd.dev**
π **Posted on**: 1787533405
π **Want more?** Click here for more info! π

