Git Worktrees are amazing, I reap the benefits of them on a weekly basis, and can’t really imagine git without them; but if I imagine myself a few years ago I don’t think I’d even be able to begin wrapping my head around them.
A second pointer
A way to visualise a git repository is that you are sitting with a Directed Acyclic Graph of commits, and when you are looking at a project on your computer you are pointing to a singular commit.
There is a notion of named branches which simplifies moving around – you can git checkout <branch-name> to quickly hop over and see what’s going on – but you can also go to a commit
with git checkout <commit>. You can find <commit> for commits on the graph by running
git log --oneline --graph. This allows you to look at any point in the history for your
project, including things outside of the main branch.
Generally this will put you into “detached head mode”, because you’re on a part of a
branch which has since been updated. To get back to wherever you were, run git switch -, or you can turn your current location into the start of a new branch with git switch -c <new-branch-name>.
So Git is keeping track of this big graph, you can interface with one commit at a time, and you can jump somewhere else by pointing at a commit/branch. The beauty of worktrees is that they give you more pointers.
How to use Git worktrees
git worktree add <path/to/somewhere> <commit or branch>
That’s it. cd to the path you gave it, you’re now sitting in a copy of your project
You can also make a worktree which points to the same location as the original pointer by omitting the commit and branch.
What’s so good about this?
This feature opens up several different workflow opportunities which help me out regularly.
Showing two versions running at the same time
I seriously can’t think of another clean way to do this, and I’d be seriously annoyed having
to live without it. A common use-case is wanting to show what the feature branch
feature/bar looks like compared to dev, but dev isn’t deployed anywhere:
git worktree add ../feat-bar feature/bar
Or you could show the changes which have been made to a project in the past month:
# This is dumb but also amazing, and relatively practical.
git worktree add ../old main@{30.days.ago}
# Or...
git worktree add ../old main@{2023-10-01}
Multitasking without git stash
git stash is a great thing to compete with because quite a lot of people agree an
alternative would be nice.
For the uninitiated, git stash gives a stack you can push changes to, and pop changes
from. If you are working on something and need to quickly swap to something else, you must
git stash -u your changes, change branch, make the change, reconcile the branch, change
back to your original branch, then git stash pop.
With worktrees, your flow is simplified:
git worktree add ../zut-alors HEAD
cd ../zut-alors
# Do the fix; commit, merge, push, etc.
cd ../repo-name
rm -rdf ../zut-alors
git worktree prune can be used to clean things up after deleting the worktree file,
but this isn’t necessary unless you reuse the worktree name.
Conclusion
Hopefully this has convinced you that worktrees are an awesome feature, but there is also a “friends we made along the way” conclusion I hope you can take away: there are a bunch of mechanisms for dancing around in Git, you just need to figure out how to take advantage of them.
If you knew about pretty much everything in this article, hopefully the
main@{30.days.ago} caught you pleasantly by surprise :)