Back to Home

Git Worktree workflow

Published on

Productivity Git Tmux

As a developer, I find myself often working on quite a few projects, and features within a project in parallel. What often happens for me, is that I often get confused in what feature I am currently working on, and may even end up commiting code to an incorrect branch. And even more commonly, I find myself needing a fresh environment before checking out a different branch to work on, or when I want to check out a colleagues piece of work.

So my previous method of creating that fresh environment, usually leads me to either creating a new copy of the repository, and having multiple copies, reserving some copies for just looking at colleagues pull request branches. These clones are usually named: project1, project2 etc, and very difficult to manage what is the purpose of each of them.

I may have some code within these repo copies that I am not ready to commit, and constantly stashing pieces of work when all I want to do is checkout a different branch for a few minutes is really annoying. There is also the paranoia too of losing important work, when doing all these stashes, it does not feel safe.

Git Worktree as an alternative worklow to stashing

This is git's very own tool for this context switching. Git allows you to manage multiple working trees of a single repository, allowing you to checkout multiple branches at the same time. No need to stash when working on a different feature, just create a new worktree! Changes within the new worktree, will have no affect at all towards your existing branch / worktree.

So even if you are bang right in the middle of a big refactor, and really don't want to budge any of the jenga code you are currently working on, but it is urgent that you work on some hotfix. The workflow is this:

  1. Use git worktree to create the new hotfix branch, and create a new worktree environment.
  2. Complete your hotfix on that created worktree.
  3. Push up your hotfix.
  4. Go back to your previous refactor worktree.

No stashing needed

Git worktree commands

I'll briefly go over this, as it is well documented by a

    man git worktree

The main commands to know are: list, add, remove

View your created worktrees for your repository to see your 'active branches' or what you are currently working on. tip Keeping this to a manageable size, helps with computer storage use, as well as keeps you focused on just a few things at a time to be more effective.

add to create a new worktree. remove to delete the worktree.

Behind the scenes

Git worktree, is similar to cloning multiple versions of the repository, however, performance is much faster, for one there is no need to download the repository, it's just created a copy of existing local repo. Also, having a separate instance for branches is a big performance improvement, on some IDE's changing branches requires indexing of the project, and on some projects may take a number of minutes. With git worktrees, the indexing is already done, and does not need to change. Checking out a branch also may take some time on really large repositories, with many file changes between the changes, git worktree, removes the complexity of your file system needing to move around files, and remove and replace.

Another use case, is also creating a worktree for older or unrelated branches. Let's say now in your project you have a .gitignore with your .npmrc, etc, and many other files that the project may use now. You may have had the terrible experience of checking out an older branch, and these files are no longer hidden by git, and end up cluttering your git working directory / git status.

My workflow

  1. Creating a new branch

Where I work we have a git branching naming convention for creating new branches, this is something probably quite standardised in typical tech organisations, and also I try to keep my own personal projects with similar naming conventions.

TypeOfChange/MFP-XXXX/short-description

an example being:

feature/MFP-3892/adding-carousel-to-home-page

Another typical part of these branches, is that most 99% of the time, we create these branches from an updated HEAD branch of the repository, instead of branching off other work in progress branches. Allowing for developers to merge in their pieces of work, without causing too many conflicts, and there is one source of truth when needing to do rebasing to resolve conflicts that do happen.

  • Optimising this: git-create-branch

I have created a CLI which speeds up branch creation by providing an interactive template of typical branch names. And will also branch by default off my desired target branch, without needing to input anything. This CLI also operates globally, so I am able to create a new branch of the project, from anywhere on my system. Also, I have shortcut CTRL+B to start the CLI tool.

Create branch demo

    • Creating a worktree

The next step is actually creating the worktree, writing down the branch names, and ensuring I am in the right directory is boring. I have also created a script that allows me to fuzzy find through all of the active branches of my project, and select one to start a git worktree for. Also, I have shortcut CTRL+G to start the create worktree script.

  • Optimising this: git-create-worktree

Create worktree demo

  1. Checking out the branch

The next part of my workflow, is simply checking out the the branch. However, I am a heavy tmux user, I also want to create an isolated environment for this git branch, so I can be focused and immersed in that new piece of work for now. And also so that I do not need to maintain my terminal tabs, or need to cd anywhere at all really. For my script I have created, I also have a list of projects which my script finds all available worktrees for, allowing me to zip through all of my active projects, personal or in my job. Also, I have shortcut CTRL+F to start the git tmux worktree session script.

  • Optimising this: git-tmux-session

Tmux worktree demo

Summary

As you can see with these scripts I can really zip around. Managing and moving around git branches is now instant, without any need to clean up current work to make space for another branch etc. Within a few seconds, and absolutely minimal keystrokes, I can get to where I want to be in a project.