DEV Community

Cover image for git-worktree: Working on multiple branches at the same time
Jean-Michel Plourde
Jean-Michel Plourde

Posted on • Edited on

git-worktree: Working on multiple branches at the same time

Cover photo by Lucas van Oort on Unsplash

The struggle

I can't count how many times I'm in the middle of something then suddenly I need to attend to a situation in the same project. I stash my current work, checkout the required branch and do some work. Then I come back to my original task and now I am confuse why everything break. Oh yeah, I forgot to unstash my changes.

An alternative could be to commit my current work, but I am very strict on what I commit and the messages I craft. When I come back to these commits, I want them to make sense and group related work.

How does it work

When using git clone or git init with non-bare repos, there is a main worktree created in the folder with the main branch checked out. Everything that is not .git inside the current folder is the main working tree. I have heard developers call that the working space or the current workspace but the correct term is a working tree.

Enters git-worktree: this command lets you create additional working trees called linked worktree. You specify a folder and git-worktree will create a linked worktree inside of it so you can checkout any existing or new branch inside of it. All you have to do then is cd into that folder and you are now working on another branch, on a working tree parallel to the main one.

No more breaking things or bamboozzling!

How I use it

In a project folder, I create a worktrees sub directory. Inside that worktrees directory, I create a subfolder for each worktree I want to add.

This makes the root of the project the main or default worktree. To switch from a worktree to another, it is only a matter of navigating folders in worktrees.

Note how

# I am in `myproject/worktrees/task-123`
# Sudden need to work on another task?
git worktree  add ../task-xyz task-xyz
pushd ../task-xyz
# do work
popd
# and we are back
Enter fullscreen mode Exit fullscreen mode

Screenshot of my terminal after creating a git worktree and using ls command to see the content

Some use cases for the command

  • You have tests that take a while to run but you can't switch to a branch because that would change files and introduce unwanted behaviors.
  • You are working on a feature and need to hop on another branch to fix some code on a submitted merge request but there is uncommitted work.
  • You want to try something quick while working on code you don't want to lose.
  • In 2025, I discovered that worktrees are perfect to work on a branche while your coding agent(s) are working on other branches simultaneously.

Getting started

Here are some useful git-worktree commands from the npm tldr page:

Terminal screenshot of the result of the npm tldr command for git-worktree

Next step

I would like to fully use git-worktree with Docker. I will explore possibilities on having different containers running in parallel from different worktrees without having to manually change the docker-compose.yml ports. Hit me up if you have a found a solution to this.

Conclusion

git-worktree allows us to work on multiple branches in parallel without forcing us to commit or stash between checkouts. I am more than happy to ditch git stash and to never look back.

I am always eager to learn from others so let me know how you work with git-worktree or in which scenarios it is helpful to you. Maybe you have an even better solution?

Top comments (11)

Collapse
 
matthewpersico profile image
Matthew O. Persico

This is pretty much what I do. Every new project gets a new worktree in the wt subdir of the repo named after the branch I am working on. All I need to do to switch projects is cd - no worry about what files will be stashed, what I lose in a branch switch, etc. In fact I have wrapped all of this in scripts that keep track of all these directories so that I type git go to get a list of them in a SELECT menu and git go <regexp. to filter the choices,

Collapse
 
jmplourde profile image
Jean-Michel Plourde

The script is a very good idea and it gives me inspiration. Do you use bare repos?

Collapse
 
matthewpersico profile image
Matthew O. Persico

Nope. I have a LARGE set of git wrappers such that when I type:

github-forknclone someorg/somerepo
Enter fullscreen mode Exit fullscreen mode
  • the repo gets forked if I haven't already
  • the repo gets cloned in ~/gits/github/org/repo
  • the command creates the directory ~/gits/github/org/repo/wt.

Then I git go somerepo to cd to ~/gits/github/org/repo and type

git worktree cre foobr
Enter fullscreen mode Exit fullscreen mode

which

  • creates the foobr branch
  • cd's to ./wt
  • creates the foobr directory
  • creates the foobr worktree, using foobr branch in the foobr directory

It's a hairy complicated mess that has grown over the past 7 years. The key to it all is that I have a function called git. Yep. I do my OWN dispatch. Otherwise, you can't add to existing git commands.

If you want to see it: github.com/matthewpersico/personal

Thread Thread
 
jmplourde profile image
Jean-Michel Plourde

That's a kinda neat solution and if that works for you that's good.

Thread Thread
 
matthewpersico profile image
Matthew O. Persico

Yeah. I keep thinking about breaking it out into its own repo,but it’s just too intertwined with lots of my utility stuff. And, it could probably use a rewrite in Python or Perl for most of the gymnastics it does in shell with git hub api. But who has the time? I cobbled it together over 7 years at my $job.

Collapse
 
otromas1 profile image
J. Carlos Guijarro

Just what I was looking for

Thanks for sharing ;)

Collapse
 
jmplourde profile image
Jean-Michel Plourde

Glad it helped you!

Collapse
 
lgrahulyadav profile image
Rahul Yadav

Loved it.

Collapse
 
jmplourde profile image
Jean-Michel Plourde

Thanks! I will update it soon enough since I've been using worktrees for a while now. What changed most is that I avoid having worktrees directly in the project folder where the .git folder is.

Collapse
 
marcomoscatelli profile image
Marco Moscatelli

Great article mate!

Collapse
 
jmplourde profile image
Jean-Michel Plourde

Thanks, your comment really means a lot to me!