What is the issue?
Working with branches is fine, as long as you are able to work on one only, or at least have the time to wrap up your work and commit some self-contained and complete state before switching to the next branch.
If you cannot complete your work, it gets messy.
Now, you can either
- use
git stash
- create a work-in-progress(WIP) commit
- just keep the modified or new files, and try to work around them and to not commit them by accident
git clone
your repository into another directory
I have done all of them, and they all have their downsides.
What is git worktree
?
Imagine git branch
on steroids.
With git worktree
you can checkout or create a new branch
into a new directory.
This means all your changes to one branch are completely isolated from your work on other branches, all your modified files, and especially also the untracked files.
But… isn’t this the same as cloning the repository into another directory?
It is not! git is fully aware of all existing worktrees.
Amongst others, this means that remotes are already set, and git offers some handy commands to work with worktrees.
Enough git worktree
(sub-)commands to be dangerous
Create a new worktree
git worktree add -b <branch_name> ../<some_directory> main
This command
- creates a new branch with the name
<branch_name>
- in a directory one level above called
<some_directory>
- based of the
main
branch
You can also use an existing branch.
git worktree add ../<some_directory> <existing-branch>
List all worktrees
git worktree list
Switch between worktrees
As worktrees are directories, you can just use your usual tooling,
e.g. cd
or pushd
and popd
.
Delete a worktree
git worktree remove <directory_name>
Every light has its shadow
After using git worktree
for a couple of days, I have come across a couple of downsides.
VS Code offers no native support, this means it does not pick up your virtual environment, as that stays in the “main location”.
Also some of my plugins do not work correctly, e.g. the Spell Checker plugin, as it does not share the word list between the directories.
For one project I need to use a compound test command, which is cumbersome to create when I need to use a longer path to the “main location”.
I created a bash alias, but ran into another issue as strace does not work with aliases.
Conclusion
Even only after using it for a couple of days,
git worktree
has become an invaluable command in my tool box.
Given the downsides, I still try to do most of my work inside the “main location”, but I am really happy to know how to avoid a mess in my checkout when it is necessary.
Thanks
Thanks to my colleague Colin Watson
who introduced me to the git worktree
command.