Skip to content

Instantly share code, notes, and snippets.

@hotzen
Last active April 22, 2026 08:43
Show Gist options
  • Select an option

  • Save hotzen/3c6dd63818f9cbb4e6a4bf9d78af20bd to your computer and use it in GitHub Desktop.

Select an option

Save hotzen/3c6dd63818f9cbb4e6a4bf9d78af20bd to your computer and use it in GitHub Desktop.
git worktree helpers
# wtswitch [query]
# Switch to an existing worktree using fzf. Works from any worktree.
# With no argument: opens fzf picker.
# With argument: if exactly one worktree matches, cd there directly.
# if multiple match, open fzf pre-filled with the query.
# if no match, exit with error.
#
# Requires: fzf
#
# Example:
# wtswitch # interactive picker
# wtswitch foo # direct cd if unambiguous, fzf otherwise
#
wtswitch() {
if ! git rev-parse --show-toplevel &>/dev/null; then
echo "Not in a git repository" >&2
return 1
fi
local worktrees
worktrees=$(git worktree list --porcelain | awk '/^worktree /{print $2}')
if [[ -z "$worktrees" ]]; then
echo "No worktrees found" >&2
return 1
fi
local selection
if [[ -n "$1" ]]; then
local matches
matches=$(echo "$worktrees" | fzf --filter="$1")
local match_count
match_count=$(echo "$matches" | grep -c .)
if [[ $match_count -eq 0 ]]; then
echo "No worktree matching '$1' found" >&2
return 1
elif [[ $match_count -eq 1 ]]; then
selection="$matches"
fi
fi
if [[ -z "$selection" ]]; then
selection=$(echo "$worktrees" | fzf --prompt="worktree > " ${1:+--query="$1"})
[[ -z "$selection" ]] && return 0
fi
echo "✓ Switched to ${selection/#$HOME/~}"
cd "$selection"
}
# wtcreate <branch>
# Create a new branch and worktree from the base branch.
# Must be called from a base repo (~/src/REPO), not from within a worktree.
# Worktree is created at ~/src/REPO.branch and cd'd into automatically.
#
# Base branch resolution order:
# 1. .worktreebase file in repo root (single line, branch name)
# 2. origin/HEAD (set via: git remote set-head origin --auto)
# 3. main or master, whichever exists
#
# Branch names are sanitized: lowercased, non-alphanumeric runs replaced
# with dashes, leading/trailing dashes stripped, truncated to 200 chars.
#
# Example:
# ~/src/myrepo $ wtcreate feature/my-thing
# ✓ Created branch feature-my-thing from main and worktree @ ~/src/myrepo.feature-my-thing
#
wtcreate() {
local branch_name="$1"
if [[ -z "$branch_name" ]]; then
echo "Usage: wtc <branch-name>" >&2
return 1
fi
local git_root
git_root=$(git rev-parse --show-toplevel 2>/dev/null)
if [[ -z "$git_root" ]]; then
echo "Not in a git repository" >&2
return 1
fi
local src_dir="${HOME}/src"
local repo_name
repo_name=$(basename "$git_root")
if [[ "$git_root" != "${src_dir}/${repo_name}" ]]; then
echo "Not in a base repo under ${src_dir}" >&2
return 1
fi
branch_name="${branch_name:l}"
branch_name="${branch_name//[^a-z0-9]/-}"
branch_name="${branch_name##-}"
branch_name="${branch_name%%-}"
branch_name="${branch_name[1,200]}"
branch_name="${branch_name%%-}"
if [[ -z "$branch_name" ]]; then
echo "Branch name is empty after sanitization" >&2
return 1
fi
local base_branch
local worktreebase_file="${git_root}/.worktreebase"
if [[ -f "$worktreebase_file" ]]; then
base_branch=$(cat "$worktreebase_file" | tr -d '[:space:]')
fi
if [[ -z "$base_branch" ]]; then
base_branch=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||')
fi
if [[ -z "$base_branch" ]]; then
if git show-ref --verify --quiet refs/heads/main; then
base_branch="main"
elif git show-ref --verify --quiet refs/heads/master; then
base_branch="master"
else
echo "Could not determine base branch" >&2
return 1
fi
fi
if ! git show-ref --verify --quiet "refs/heads/${base_branch}" && \
! git show-ref --verify --quiet "refs/remotes/origin/${base_branch}"; then
echo "Base branch '${base_branch}' not found locally or in origin" >&2
return 1
fi
local worktree_path="${src_dir}/${repo_name}.${branch_name}"
if [[ -d "$worktree_path" ]]; then
echo "Worktree already exists: ${worktree_path}" >&2
return 1
fi
if git show-ref --verify --quiet "refs/heads/${branch_name}"; then
echo "Branch '${branch_name}' already exists" >&2
return 1
fi
git worktree add -b "$branch_name" "$worktree_path" "$base_branch" || return 1
echo "✓ Created branch ${branch_name} from ${base_branch} and worktree @ ${worktree_path/#$HOME/~}"
cd "$worktree_path"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment