Working With Many Branches — Using Git worktree

How Git worktree can help you avoid some of the problems that arise when handling multiple branches in Git.

David Groemling
Cloud Native Daily
5 min readJun 10, 2023

--

Photo by Jan Huber on Unsplash

Git what? You’ve read right. Git has a very helpful but rarely used feature called worktree.

Did you ever run into a scenario where you had to do a quick bugfix, check out a colleague's branch for reviewing it or just wanted to see how a piece of code works on another branch?

We all prefer working on just one thing and avoiding mental context-switching as much as possible. However, every once in a while, reality kicks in and you are forced to work on more than one branch at once. When this happens, at least the tooling shouldn’t be an extra hurdle in your way. So how can you achieve this with Git?

Naive approach — Simple checkout

The most straightforward and probably common approach is to stash your current changes or put them in a temporary commit before you do a git checkout <target-branch>. This command will give you all the files tracked by git in the version of the target branch.

Switching the branch like that had disadvantages though:

  1. Recompilation: Depending on your programming language and how incremental builds are handled, you might have to rebuild a lot of your codebase. What’s worse, if you forget that recompilation, you might end up using artifacts that were compiled using a different source code than what you’re seeing in your IDE.
  2. Complicated process: If you stash changes, you need to remember to reapply the changes. If you need to do this kind of switching a lot, you also need to remember, which stashed changes to reapply.
  3. Broken git history: If you create a temporary commit, you need to remove it before raising a PR or you end up with meaningless things in the git log. Unhappy and confused co-workers come for free :)

Cloning the repository multiple times

One way I’ve seen people work around this is by cloning the same repository multiple times in different directories. In each of these clones, you can check out branches independently and when your working on that branch is done, you can push the changes.

While this avoids the disadvantages of switching branches, it has other major price tags:

  1. Resources: Cloning the same repository more than once means, you need to download and store the full history more than once on your laptop. This may not be a problem if your repository is small, but over time it could become an issue.
  2. Management: Having the repo checked out multiple times means, you need to git fetch/git pull in all of them. If you don’t make sure that you update them all around the same time, each clone has a different view of the world. You may be thinking, that you are working on top of a change that recently went into the main branch, only to realize that you forgot the update the specific clone you’re working with.

Git worktree to the rescue

Git Worktree is a solution similar to multiple clones but without the resource and management overhead.

Need to do a quick fix without touching your current changes?git worktree add bugfix -b bugfix-branch will create a new directory called “bugfix” and create and checkout a new branch in it called “bugfix-branch". From there on, continues as you normally would in that directory.

Want to check out a colleague's branch?git worktree add <target directory> — checkout <branch> is your command. It will checkout an existing branch in the target directory.

Want to compare how your branch behaves compared to the main branch? In fact, I usually do all my work in a Worktree and leave “main” checked out in the original directory. That means I can easily run or debug both versions side by side, it’s just a matter of running the same run or debugging commands in two different directories.

Want a simple overview of all your worktrees? Run git worktree list, and you’ll get an overview of all worktrees with respective branches and commits, like so:

A screenshot showing the output of git worktree list. The output lists three directories along with the branches and their commits checked out in those directories.
A screenshot showing the output of git worktree list.

But how is this better?

At this point, you’re probably wondering, why worktree is any better than multiple clones. The last command above, which gave you a simple overview is the first part of the answer since this would not be possible with multiple copies. Worktrees are easier to maintain because Git knows about all of them.

The second part is: You don’t actually have multiple copies of the repository. You still have just one. Instead of creating clones of the full history and state, it merely links one directory to another. Avoiding these copies is faster, requires less storage and is easier to manage.

This becomes most visible if you actually look at the generated files:

main contains the original clone, while bugfix and review are the extra worktrees. As you can see, all of Git’s metadata is in .git inside main. The .git objects in bugfix and review are in fact files that are just linking to the original directory:

Screenshot of a .git file, linking back to the main directory.
Screenshot of a .git file, linking back to the main directory.

Conclusion

In this article, I described how Git worktree can help you avoid some of the problems that arise when handling multiple branches in Git.

If you are interested in similar topics feel free to follow & subscribe :-)

--

--