Git Worktree – one or more?


In my daily work, I often deal with multiple folders containing repository data. I used to work with separate repositories, but then I switched to using one repository with multiple worktrees. I must say that the ease of use and convenience of this solution are so great that when I was thinking about the next Git topic to discuss, the decision was obvious – I had to write about Git worktrees.

Firstly, why would I want to have more than one folder containing repository data? It’s quite obvious if you have multiple tasks to work on simultaneously. Imagine that you are developing something on one branch and suddenly you are assigned a small but urgent bug to fix. You could stash your work or switch to another branch, but it can be cumbersome if the switch requires additional work.

Usually, switching branches involves tasks such as time-consuming recompilation of new sources, changing database configurations, or even dealing with issues caused by changes in the repository structure (especially if you are working with a legacy system).

But why not have two clones of the same repository? You might think of having multiple sibling folders containing clones, right? Yes, that’s a possibility, but there is something even better – worktrees.

What is a worktree?

You may recall my explanation about Git branches. A branch is simply a pointer to a specific commit. When you commit a new code, the branch pointer moves to the new commit.

Branch is just a pointer to the specific commit

Git allows having only one „active” pointer (branch) at a time. This pointer not only represents a branch but also represents your working tree. However, there is an option to have multiple working trees simultaneously. In practice, this means that you can have multiple branches checked out in parallel.

With multiple worktrees, you can work on different branches simultaneously, each in its own worktree.

Advantages of having multiple worktrees

You can have multiple clones of the same repository, each with its own worktree, or you can have one clone with multiple worktrees. Both solutions work similarly, but there are some differences:

  • Separate clones consume a lot more disk space since each clone has its own .git folder, whereas worktrees share the same .git folder. (This issue can be mitigated by using the –local flag during cloning.)
  • Separate clones allow you to switch to the same branch at the same time, which may seem like a good idea at first glance, but in practice, it brings more problems than advantages.
  • If you want to sync with the master branch in separate clones, you have to pull from the remote multiple times. With worktrees, only one pull is needed (which is a great feature!).
  • Multiple clones increase the probability of having problems with stale, old, or unused/forgotten branches over time.
  • Multiple worktrees/clones allow you to compare files using standard diff tools (even something as simple as Notepad++ would suffice).

And probably many more.

How to create multiple clones?

Creating multiple clones of the same repository is straightforward. It requires running the cloning command multiple times.

git clone reponame

After that, you will have multiple independent repositories, and you can easily check out the same branch in all of them.

Clones listed in the SmartGit
SmartGit provides an even easier way to clone multiple repositories

How to create multiple worktrees?

Creating worktrees is equally easy.

git clone -q
cd .\LawnMover
git worktree add -b GDItoBMP C:\MultipleWorktrees\LawnMover-Worktree1
Preparing worktree (new branch 'GDItoBMP')
HEAD is now at 251855c Brakes behavior slightly changed (vehicle stops if no arrow pressed)
git worktree list
C:/MultipleWorktrees/LawnMover 251855c [master]
C:/MultipleWorktrees/LawnMover-Worktree1 251855c [GDItoBMP]
cd C:\MultipleWorktrees\LawnMover-Worktree1
git checkout master
fatal: 'master' is already checked out at 'C:/MultipleWorktrees/LawnMover'
Worktree creation
Worktrees look almost exactly the same as separate clones

I only have one additional worktree because there are no more branches in the repository. As I mentioned earlier, worktrees cannot have the same branch checked out (although there is a -f (force) switch that allows it).

Forcible creation of the worktree with the same branch checked out

Under normal circumstances, we don’t work with worktrees like that. Anyway, now we have one repository with multiple worktrees. When I pull from the origin and switch to the other worktree, I will see the latest changes there too.

I think that’s everything I wanted to say about worktrees in Git. I hope you will try this feature and enjoy using it.

And now for something completely different

Or maybe not completely different. I just want to delve into the mechanics behind worktrees. How does Git know if multiple worktrees exist, where they are stored, or which branch they have checked out? It’s very simple and straightforward. As with any other Git-related mechanics, we need to think about the .git folder.

We now have the repository cloned and one additional worktree added. All of these are located in the „c:\multipleworktrees” folder.

The „LawnMover” folder contains the cloned repository, and it is the only one that contains the hidden .git folder (Git’s heart – its database).

Git’s heart – its database

The „LawnMover-GDItoBMP” folder contains the worktree data. It means that it stores the code files and a .git file (not a folder) with only one line inside – the location of the master repository’s database.

Contain of the .git file – pointer to the a

Let’s take a look at „C:/MultipleWorktrees/LawnMover/.git/worktrees/LawnMover-GDItoBMP.” We can see that the .git database contains a „worktrees” folder that stores data for the two worktrees. As I mentioned earlier, a Git repository always contains at least one worktree (except for bare repositories, which is a different topic). Here, we can see folders that reflect the two worktrees that we currently have. „master” in the cloned repository and the second one, newly created in a separate folder: „LawnMover-GDItoBMP.”

Each of these folders contains its own set of pointers (like HEAD) or an INDEX file (staging area contents). So, the main point is that when we have multiple worktrees, the .git database is shared among all of them. That’s why we don’t need to pull from the master separately for each worktree, as we would need to do for multiple clones. If you need a very detailed explanation, please refer to the official Git documentation describing the worktrees feature. For our purposes, the knowledge provided here should be more than enough. The most important thing is that you now know that worktrees exist, they are useful, and they are easy to maintain.

I hope you will make use of this new knowledge.

0 0 votes
Article Rating
Powiadom o
0 komentarzy
Inline Feedbacks
View all comments