I learned about git worktrees from a non-obvious place: GitButler. GitButler has a concept of lightweight integration branches managed as a ‘workspace’ and they are—as far as I can tell—implemented using git worktrees.

I’m so used to my typical local workflow that the benefits of git worktrees took a while to sink in.
Before #
cd ~/my-repo/directorygit fetch && git pull– get the latestgit checkout -b bugfix/some-bug- Work away and possible
git stashat some point because I need to switch to another branch likemainorsome-other-featuremid-flow. git add .on mybugfix/some-bugbranch.git commit -m "some message"git checkout mainthengit fetch && git pullagain to make sure I’ve got the latest.git checkout bugfix/some-bugthengit rebase mainto pull in and resolve any issues re-integrating withmain.git checkout mainthengit merge bugfix/some-bugto merge the changes intomain.- Typically
git pushto push the changes to the remote repository.
After #
mkdir -P ~/projects/cool-project– Make a directory to contain multiple folders for my work, starting with the main branch.cd ~/projects/cool-project– again, not a git repo but a parent folder into which I’ll be cloning the repository then creating worktrees.git clone https://github.com/username/cool-project.git main– Clone the repository into a new subdirectory calledmain. This is important: I now have a directory containing the main branch and I’ll leave this as the main branch on my local machine.cd main– Now I’m in the git repo for the main branch.git worktree add ../my-feature1 -b feature-1– This is the new bit. After this I have a new directory adjacent to the main directory calledmy-feature1. This is where I’ll work on my feature branch.My feature branch called
feature-1is instantly available in my main directory (repo) as well!cd ../main && git branchincludesfeature-1in the list of branches. Amaze!Work work work.
Still have the usual two options to merge work. It’s just folder-based:
| |
- Finally, you can cleanup.
Either
rm -rf ../my-feature1 && git worktree pruneorgit worktree remove ../my-feature1
Example #
I’m working on the web app for CalcMark.
I have baseline directory called ~/projects/calcmark and into that I cloned my main branch as calcdown-web.
Then I’ve been working on a couple of different branches as you can see:
| |
Or for git’s world view:
| |
The thing I’ve really been enjoying is just cd-ing into branches without having to git stash and git stash pop constantly, or worse yet git add-ing files just so I can switch branches.
Sounds basic, but it’s made my life a little easier.
Advantages #
- Work on multiple branches at the same time without stashing or staging files.
- Compare WIP. For example, I can
npm run devin both of my worktree folders and see the differences in the browser. - Space efficient.
I’m not dealing with massive repos, but it’s nice not to litter my disk with copies.
git worktree-s just have one copy of the files:
| |
Branch protection. You actually can’t checkout the same branch in multiple worktrees. It’s a good feature because I think we’ve all probably, at some point, ended up with multiple versions of
mainon our local machine :-\1 2 3 4# In main worktree (on 'main' branch) cd ../feature1-worktree git checkout main # ERROR: 'main' is already checked out at '~/projects/cool-project/main'