Git worktrees: a smoother alternative to stash, switch, pull, repeat
Git worktrees provides an improvement for developers tired of stashing and switching branches
In my current work as a consultant I use AI agents to code many of the features I am working on. While searching for a solution to having multiple agents work on the same code, independently, I became aware of git worktrees via Cassidy Williams’ post on the GitHub blog, “What are git worktrees, and why should I use them?”, which provides a smoother and faster workflow for this. Apparently, git has had this feature since 2015, so I am a bit late to the party, but I wish I knew about it earlier.
While it appears that git worktrees solves some of my issues with multiple agents (a later post), I discovered that it solved one of my more annoying workflows:
I often find myself needing to switch between branches when working on bugs etc. Until now my workflow has been to stash, switch, pull, repeat. It is both time-consuming and just annoying to do it.
It appears that git worktrees is a more efficient way of having multiple, ad-hoc named, clones of the same repository (instead of having multiple long-lived generically named clones). My separate clones are called e.g. clone1, clone2 etc. which is not very telling of the actual work being done, and each repository requires fetching the full history - this might be a problem if the repositories contain a lot of history. Worktrees re-uses an existing clone and it is possible to give it a telling name because it is more ad-hoc driven.
The old workflow: stash, switch, pull, repeat
My workflow until now was this: I am working on a new feature and there is some other task that requires a new fresh branch from main.
So I stash my work (I don’t bother adding a message):
git stash push
Switch to main and update it:
git checkout main
git pull
Create a hotfix branch:
git checkout -b hotfix-approval-button
Fix it, commit, push:
git add .
git commit -m "Fix broken approval button"
git push
Then, after the PR merges I switch back:
git checkout feature-new-approval-flow
git stash pop
If the stash, switch, pull workflow requires too much work, I would switch to a second (or third) clone and do the work there.
Enter git worktrees
The idea is simple: a worktree lets you check out multiple branches at the same time, each in its own folder, all backed by the same underlying repository.
That same urgent-bug scenario now looks like this. From my feature branch, without touching anything, I create a new worktree based on main:
git worktree add ../hotfix-workspace -b hotfix-approval-button main
This instantly creates a sibling folder called hotfix-workspace, based on main, with a fresh branch hotfix-approval-button checked out. The original folder stays the same.
I can now fix the bug, and ship it:
cd ../hotfix-workspace
# ...fix fix fix...
git add .
git commit -m "Fix broken approval button"
git push
Once the PR is merged, I remove the throwaway worktree and go back to my feature, which never moved:
cd ../my-project
git worktree remove ../hotfix-workspace
A few useful commands:
# See all your worktrees and which branch each has checked out
git worktree list
# Add a worktree for an existing branch
git worktree add ../review-pr-123 feature-xyz
# Clean up references to folders you deleted manually
git worktree prune
Things to be aware of
A few things to be aware of:
- Dependency bloat. Each worktree is its own folder, so each needs its own dependencies (same as multiple clones)
- Folder housekeeping. Worktree folders do not clean themselves up. Remember to use
git worktree remove(orprune). .gitignoregotchas. If you create worktree folders inside your main repo, add them to.gitignoreso you don’t accidentally track them. I prefer creating them as siblings (../) outside the repo to sidestep this entirely.- One branch, one worktree. Git won’t let you check out the same branch in two worktrees at once.