Rethink your git workflow with git-worktree
Git is a powerful tool used by almost everyone in the the tech industry. Worktrees are an often overlooked feature that is presented in this article.
Git is an immensely powerful tool with a vast set of features. Worktrees are one feature that was unknown to me until recently, and boy do I wish I had discovered it sooner.
When working in a team, especially when working on larger codebases, it will be common to switch branches frequently. I usually
git stash any uncommitted changes or simply
git commit -m "wip" them. This can quickly get out of control when I switch multiple times and then become complicated when juggling numerous different stashes.
Git worktrees are a fantastic solution to improve this workflow. It's not a new feature by any standard. It has been around for years.
What is git worktree?
"Manage multiple working trees attached to the same repository."
git switch <branch> to another branch, your working directory will be changed in place. The changes from the other branch are no longer directly accessible. This is precisely why you have to stash or commit any changes before switching. With a normal
git clone you get exactly one working directory.
With git worktree you can have multiple directories for the same repository. Each worktree will point to a different commit/branch. This opens up the ability to quickly switch between branches without interrupting your current work.
I personally started using worktrees to check out code from other people's PRs for review or development or to simply switch to a different set of work when I get stuck on something.
Git worktree requires that you create a bare clone of your repository. This will look a bit weird if you haven't seen it before. Instead of a
.git directory alongside your code, you will have a directory with all the contents that normally go into
git clone --bare https://github.com/golang/go.git
With this on your disc, you can now create a worktree by typing:
git worktree add master
This will create a new folder inside your bare clone with the name
master that will contain all the code from the master branch. From there, you can interact with your code and git just like you usually would.
At this point, we've just reached feature parity. The usefulness of this feature becomes apparent the moment you create a second worktree, i.e., to work on a separate ticket:
git worktree add feat-123
You now have two separate versions of your code side by side that you can work on without having to stash or commit code when switching between branches.
We can just as easily remove worktrees we no longer need with
git worktree remove feat-123
Despite their usefulness, I haven't found great support for worktrees in code editors. There's an open issue for VSCode requesting support for worktrees, but it seems it's lacking community support to get something shipped.
There exists a plugin for neovim however, that was written by popular twitch.tv streamer ThePrimeagen. This plugin allows rapid switching between and managing worktrees from within neovim. He even explains the concept and his plugin in a video on Youtube:
Git worktree is a hidden gem that is unknown to many. They can drastically help simplify development workflows by allowing users to switch between branches without committing their work quickly.
I'm almost mad I hadn't discovered this feature of git sooner. The number of times I have lost some of my work in a messy git stash could have easily been zero had I used worktrees from the get-go.