me, contemplating how to get out of vim again
me, contemplating how to get out of vim again

Image: Tim Gouw

Get Back to the Future painlessly with git worktree

Tags: git, web dev, version control, time travel

July 06, 2018

Git is complicated...

Git can sometimes make your head spin. I know I am safe in assuming that I'm not alone in this feeling because sites like 'Oh Shit Git' exist.

ohshitgit_com

Git is fast, scalable, and distributed so it's awesome for projects from tiny to quite large (note that it's not super performant for repos >1gb or files >100 MB).

Time Travelling with 'git worktree'?

Time travel is often a reference point for git's complexity but I'd argue that its rich command options make it quite robust for handling all sorts of situations. But it is quite true that with git, we are given the ability to time travel. We can check out any point in time that was tracked by a git commit. And since around 2015, we've had an often unnoticed additional ability: to checkout two points in time simultaneously.

I am referring to:


git worktree add [branchName] [targetDir]

This command lets us manage multiple working trees (think, multiple local clones) attached to the same repository.

When to use 'git worktree'

The utility of the command is in allowing you to locally check out more than one branch at a time. A new working tree is created in the directory specified in the command and associated it's with the repository. This new working tree is called a "linked working tree" as opposed to the "main working tree" resulting from "git init" or "git clone". every git repository has one "main" working tree association (assuming it's not a special case like a bare repository) and any number (0-whatever) associated "linked" working trees.

brace-yourself

So, when you're testing some bug fix or a new feature, you may find it useful to compare the software behavior before and after the fix was applied. Similarly, this can be quite useful for developers to make tweaks and ensure no regression is introduced inadvertently.

Example workflow using 'git worktree'

The basic workflow I find myself using is:


    # Checkout new feature branch
    $ git checkout origin/feature/thingy

    # Build and start, and test the new feature
    $ git worktree add -b feature/thingy/old
      ..thingy origin/master

    $ cd ../thingy
    # Switched to a new branch 'feature/thingy/old'

    # Build and start, and test
      using the new feature branch
      

I find that I typically spend most of my time comparing (step 6). However, sometimes urgent issues or 'hot-fixes' are sent my way. In those cases, I use git worktree for both the feature branch under test as well as the "previous-behavior" branch. This is great because it allows me to context switch with less frustration, no stashing, temp commits, aborting merge conflicts, etc.

Hotfix example workflow

Developers also can use git worktree for quickly reacting to production issues or other urgent matters requiring a hot-fix. This workflow illustrates how that is accomplished:


    $ git worktree add -b hotfix
      ../hotfix origin/master

    # Enter ../hotfix, identifier hotfix
    # Branch hotfix set up to track
      remote branch master from origin.

    $ cd ../hotfix
    # Switched to a new branch 'hotfix'

Conclusion

In summary, multiple work trees let us multitask across different versions of a project seamlessly. I hope you can find some benefits from this helpful command.


Loading...

© Copyright 2023 Nathan Phennel