Adam Israel

Adam Israel

An economy of words.

Adam

3-Minute Read

Often enough, you’re at the stage in your work where you’re running potentially time-consuming unit/integration tests. You have other work to do on that project, but you’re tied up waiting for the tests to finish (and hopefully pass).

I wanted to figure out an efficient way to work on new features while I’m testing another. You can’t switch the branch out from underneath the test, and making a copy/clone of the repository is an expensive operation (in disk space and/or network speed, especially with larger projects).

And I found git-worktree:

A git repository can support multiple working trees, allowing you to check out more than one branch at a time. […] a new working tree is associated with the repository, […] called a “linked working tree” as opposed to the “main working tree” prepared by “git init” or “git clone”. A repository has one main working tree[…] and zero or more linked working trees.

Example

Here’s what it looks like in practice.

Create a new project

Create a new, empty project to work from (if you’re brave, skip this step and work against an existing repo):

mkdir -p ~/Demo/myproject
cd ~/Demo/myproject
git init .
touch README.md
git add README.md
git commit -a -m "Initial response"

Create a Feature Branch and worktree

The master branch should only contain code ready for general consumption. I use branches to work on new code, and merge when ready.

cd ~/Demo/myproject

# Checkout the branch you want to base your new work on
git checkout master

# Create a new branch for this mythical new work
git branch feature-24601

# Create a new worktree, in the Demo directory, for our new feature branch
git worktree add ../myproject-24601 feature-24601

# Switch to the directory with the new worktree
cd ../myproject-24601
# Confirm that we're in our new branch
git status
> On branch feature-24601

Hack/Hack/Hack

Now you’re free to hack on your new feature without stomping over your running tests.

# Write code, test, and documentation
echo "Adding feature 24601." >> README.md
git commit -a -m "Document new feature"

Merge feature branch

Switch back to master and merge your new feature.

cd ../myproject
git merge feature-24601
Updating 873ef32..2da1c53
Fast-forward
 README.md | 1 +
 1 file changed, 1 insertion(+)

Cleaning up

When you’re done, clean up your repository. Future you will be happier.

# `prune` will remove worktrees pointing to directories that no longer exist
rm -rf ../myproject-24601
git worktree prune

# Delete the feature branch
git branch -d feature-24601
> Deleted branch feature-24601 (was 2da1c53).

Caveats

  • Mixing worktree and submodules works but with the caveat that each worktree has a unique copy of submodules, rather than a hard link, so this will consume more disk space.
  • You can’t create multiple worktrees for the same branch, but that’s generally not a problem if you’re following best git practices.

Further Reading

comments powered by Disqus

Recent Posts

categories

About

This website is the digital home of software engineer, author, and genealogist Adam Israel.