Git Worktrees In Use
Written by Preston Lamb
Posted on May 18, 2022
Most of us use Git every day, but generally use only the features that we are familiar with and allow us to do our job. There's nothing wrong with this at all, but learning new tricks can take your productivity up a level! With that in mind, let me introduce you to Git Worktrees.
Git Worktrees allow you to pull a git repository to your computer and then work on multiple branches at a time if desired. A standard
git clone command pulls the repository to your machine and starts you working on a particular branch. If you need to switch branches, you have to either commit and push your code or stash the changes. When you clone the repo with the intent to use worktrees, you don't check out a particular branch initially. Let's learn how to use Git Worktrees!
Let's start by cloning the repository to your machine.
$ git clone --bare firstname.lastname@example.org:pjlamb12/worktree-demo.git worktree-demo
The above command looks similar to your normal
git clone, with one important extra piece:
--bare. This flag is what clones the repo to your machine without checking out a particular branch. You can read more about the flag here. The last part of the command,
worktree-demo, names the folder that the repository will be cloned into. Normally
git clone will clone the repo into a folder that's named the same as the repository URL, minus the
git clone --bare will keep the
.git extension on the folder when cloning. If you don't want the
.git on the folder name, provide the name of the folder as I've done above.
At this point, you have the repository cloned to your machine. If you change into the directory and list the contents, you'll see a few files like
description, along with a couple folders like
objects. This is just an example; yours may not be exactly the same.
If you run the
git status command, you'll see an error that says something along the lines of, "this operation must be run in a work tree". This lets you know that you can't do any work on your repository in this main folder. Let's look next at how to create a worktree so you can make some changes to your app.
Let's add our first worktree, which we'll call
main and will be based off the
HEAD of the repo. You can add that worktree like this:
$ git worktree add main
If you list the contents of the directory, you'll now see a new folder called
main. If you change into that directory and list the contents you'll see your application code. Also,
git status will now give you the status that you expect to see. You'll no longer see the error mentioned above.
You can now always view the code in your repository at the
main branch. To update the worktree, run the
git pull command. This will get all the latest commits to the branch and update your worktree. I recommend not doing any work on your application in this worktree, however. This worktree is useful to have on your computer and ready to go so that you can troubleshoot any issues that teammates may be having, for example. If you want to make a change to the application, create a new worktree just like you would create a new branch.
The command to create a new worktree and a new branch is similar to the
add command above, but with an extra flag.
$ git worktree add -b my-new-branch worktree-name
The flag you need to provide is the
-b branch-name flag. Whatever you use as the value for this flag will be the name of the branch when you push it to the repository. The last argument,
worktree-name, is the name of the worktree on your computer and will be the name of the folder where the code is stored. This command does the same thing as the first
add command, but a new branch is created with the given name.
Now that you have a worktree and branch created to make your changes, you can work on your application the same as you always do. Make changes, commit them, push them, and then merge the pull request. The first time you push the code, remember to use the
$ git push --set-upstream origin my-new-branch
After you've used this flag the first time,
git push will suffice.
The above commands are helpful but don't cover all situations. Sometimes you need to help your coworker with an issue they are seeing on their branch. This is where you can really see the benefits of worktrees. You can leave the worktree that you're working on untouched on your machine, and add a new worktree based on your coworker's branch. You can add this new worktree like this:
$ git worktree add worktree-name branch-name
Again, this is similar to the first
add command but the
branch-name argument will start you off on a branch in the repository instead of from the
HEAD commit. You'll be able to change into the worktree folder and browse the code as your coworker is seeing it, but you won't have been required to commit your unfinished code to switch branches.
Often when you're working on a feature branch the main branch has someone else's code merged to it. At that point you'll need to update your feature branch with
merge. These same methods of updating your worktree can be used. You can update your worktree by rebasing or merging. You can decide the which method you would like to use. This article explains the differences between
Before merging or rebasing, make sure that your local
main worktree has been updated with
git pull. After your local worktree is updated, you can
rebase your feature branch.
After you finish up with a worktree, you'll want to remove the worktree from your machine. Each worktree will take up space on your hard drive, so you'll eventually run out room if you don't remove unused workspaces. You can remove them with the
$ git worktree remove worktree-name
The worktree and all related files will be removed from your computer.
If you need to list the worktrees you've created, you can use the
$ git worktree list
This will list all the local worktrees you've created on your machine.
When I found out about worktrees, I could see the potential benefits immediately. The ability to have multiple branches checked out on your computer at a single time is really powerful, especially when working with a team. Gone are the days of committing completely unfinished code to your feature branch so you can switch branches to help a coworker. It's not necessarily a "one size fits all" solution, but I'm excited about the possibilities. Hopefully this article helps you get started!