The letter A styled as Alchemists logo. lchemists
Published October 27, 2019 Updated May 15, 2020

Git Worktree

Demonstrates using Git worktrees for jumping between various contexts without losing or disturbing existing work.


# Hello and welcome to the Alchemists Screencasts!
# Today, we'll look at the Git Worktree ( command.
# For demonstration purposes, a *demo* project has been created:

cd demo
ls -alhT

# Git Worktree support was added in Git 2.5.0.
# It allows us to work in a linked directory with full capabilities of the main repo.
# There are several benefits:
# - Crafting a quick fix without disturbing your current workflow.
# - Temporarily reviewing someone's feature branch.
# - Running separate tests.
# ...etc...
# Here's a quick example of working with a detached head:

git worktree add --detach ../demo-detached HEAD
cd ../demo-detached

# Notice my shell prompt no longer contains Git information.
# This happened because we are in a linked Git folder.
# We can verify by inspecting the ".git" file.

cat .git

# We can use full Git features, though:

git status --short --branch

# As well as view branch info, etc...


# What if we want to work on a feature branch instead of a detached HEAD?
# Here's how:

cd ../demo
git worktree add -b "manual" ../demo-manual master
cd ../demo-manual

# The use of `-b "manual"` is important as this gives us a "manual" branch to work with.


# Now we can commit work to our "manual" branch as usual:

touch example.txt
git add example.txt
git commit --message "Added example file."

# Great but what happens if we run specs?


# As you can see from the stack dump, our `config/database.yml` is missing.
# This is due to `config/database.yml` being ignored by `.gitignore`.
# We can use my `gwa` shell function to resolve this situation.
# Think of the function as `git worktree` on steroids. 🎉
# Here's the function's source:

cype gwa

# The bulk of this function is dealing with worktree option behavior. Example:

gwa automated

# The second-to-last line is what makes it powerful!
# Let's zoom in on that line (as the top of the function:

cype gwa | ag --after=1 rsync | head -1

# Here we use `ls-files` + `rsync` to copy the normally ignored/untracked Git files.
# This makes it possible to build a fully functional worktree.
# Here it is in action:

cd ../demo
gwa automated d
direnv allow

# Not only did the function setup the worktree but it moved us into it.
# All via a single command!
# If we run specs, everything works because rsync copied the ignored/untracked files for us:


# Enjoy!
# ☿ 🜔 🜍 🜂 🜃 🜁 🜄