For being in the Git source code for almost a decade, I have only very rarely heard them mentioned, let alone used, at work. Nevertheless, there are specific situations where you would wish for worktrees.
Foo1
The earliest documentation I can find on Git worktrees dates back to version 2.5.6, released a little over 8 years ago now in 2017. It provides an example for when you might consider using worktrees:
You are in the middle of a refactoring session and your boss comes in and demands that you fix something immediately. You might typically use git-stash[1] to store your changes away temporarily, however, your worktree is in such a state of disarray (with new, moved, and removed files, and other bits and pieces strewn around) that you don’t want to risk disturbing any of it. Instead, you create a temporary linked worktree to make the emergency fix, remove it when done, and then resume your earlier refactoring session.
Unfortunately, it does not clarify any further what is meant with “state of disarray”, so to me it remains unclear what advantage this really brings over stashing your changes.
Nevertheless, I have not too long ago started to use worktrees. In my professional world we have come to a point where the full test suite of end-to-end tests we are running to check our data pipelines function as expected, exceeds around half an hour. In this scenario, I use worktrees for a singular reason:
While waiting for the end-to-end tests on one branch to finish, I can work on other features in parallel.
Stashing vs worktrees in practice
- It seems to be a bit of a hidden feature, because most people use a "stashing" workflow.
- However, there are cases where you cannot get around using worktrees.
- Either wait, or clone a separate Git repository.
- Explain how it compares to the workflow of stashing changes.
- This workflow never really bothered me.
- Guix is another good example where Git worktrees work well
- Multiple branches you might want to track and you want to check whether a package builds successfully.
- Downside is of course more complexity
- You have to keep track of the worktree of your current working directory. You have to initialize files not tracked by Git, such as a virtual environment, in each working directory.
- If you move a worktree without using Git, you will need to repair it, since they are of course linked by "pointers" in gitdir and the .git file.
- How do I use worktrees in practice
- I like to start out with the "stashing" workflow and when it turns out I need worktrees, I will add them as necessary.
- In this case, my original worktree which contains the .git directory, I will point at the main branch, and development takes place in a different worktree.
- + and @ to separate them. It is easy and consistent to filter for these symbols or filter them out when I want to switch to my main worktree. I could delete all directories with + and @ and not lose any data. This is compatible with the single worktree flow.
Read the docs
- The most up to date Git worktree documentation.
- In the documentation of my current Git version, it is stated that worktrees can be locked, so they will not be automatically pruned. (What was pruning again?).
- For example, this is useful for portable devices or network shares.
- A use case I could imagine is embedded systems. For a worktree you do not need to store the entire .git directory in your working directory. Instead, a .git file linking to (what exactly?) is created. This means you can still use all Git commands for version control, but do not need to store the entire history when you are already constrained by memory.
- Example at the bottom of the documentation does not paint the full picture: Some things cannot be easily stashed, such as directories not tracked by Git.