Skip to main content

A Better Way to Worktree

· 2 min read

After getting worktree-pilled by Primeagen, I've consistently been using worktrees for the past two years.

But I recently learned git clone --bare is suboptimal – there's a better way to clone a repo for worktree usage that doesn't require creating extra branches just for the worktree workflow.

Here's the fastest, cleanest way I've found to clone a repo for usage with worktress. Works every time, without needing to run git gc all the time to clean up storage bloat.

I use it in zsh, but it should work in bash. Fish bros, sorry I have no clue.

function git-empty-clone() {
# Useful for cloning a repo suitable for use with git worktrees
# Taken from this stack overflow answer:
# https://stackoverflow.com/questions/54367011/git-bare-repositories-worktrees-and-tracking-branches
if [ $# -lt 2 ]; then
echo "Usage: git-empty-clone <repo-url> <target-dir>"
return 1
fi

local repo_url="$1"
local target_dir="$2"

git clone "$repo_url" "$target_dir" || return 1
cd "$target_dir" || return 1

# Create an empty root commit
local empty_tree
empty_tree=$(git hash-object -t tree /dev/null)
local empty_commit
empty_commit=$(echo | git commit-tree "$empty_tree")

# Checkout the empty commit in detached HEAD
git checkout "$empty_commit"
echo "Use git worktree add <branch_name> to start using worktrees."
}

Example usage to clone my vim configs and add a worktree for the dev branch:

git-empty-clone git@github.com:whoislewys/vim_runtime.git vim_runtime.git
git worktree add dev

Read the thread in the function's comment to learn why it works and uncover the mystery of the git empty tree: https://stackoverflow.com/questions/54367011/git-bare-repositories-worktrees-and-tracking-branches