Skip to content

Instantly share code, notes, and snippets.

@leocaseiro
Last active April 10, 2026 00:30
Show Gist options
  • Select an option

  • Save leocaseiro/f53bfa021f47961cd62cb0278e5ab58b to your computer and use it in GitHub Desktop.

Select an option

Save leocaseiro/f53bfa021f47961cd62cb0278e5ab58b to your computer and use it in GitHub Desktop.
Git Worktree Helpers (alias commands for terminal)

git-worktree-helpers.zsh

Zsh helpers for navigating git worktrees faster.

Commands

Command Description
gwtr List all worktrees sorted by last modified (newest first)
cdwt Open an interactive fzf picker to cd into a worktree
cdwt <path> cd directly into a worktree path (with tab-completion)
gwtb Jump back to the previous worktree

Dependencies

brew install git fzf
Dependency Min version Required for
git 2.5+ worktree support
fzf any cdwt interactive picker
zsh any completion system

Install

1. Source directly from your .zshrc:

# Download
curl -o ~/.git-worktree-helpers.zsh \
  https://gist.githubusercontent.com/<you>/<gist-id>/raw/git-worktree-helpers.zsh

# Add to ~/.zshrc
source ~/.git-worktree-helpers.zsh

2. Or paste the contents directly into your ~/.zshrc.

Then reload:

source ~/.zshrc

Note: Make sure compinit is called in your .zshrc before sourcing this file, otherwise tab-completion for cdwt won't work.

autoload -Uz compinit && compinit

Usage

# See all worktrees sorted by recent activity
gwtr

# Pick a worktree interactively (↑↓ to navigate, Enter to jump, Esc to cancel)
# Preview panel shows last 10 commits of the highlighted worktree
cdwt

# Jump directly with tab-complete
cdwt /path/to/my-feature-worktree

# Toggle back to where you were
gwtb
# ─── Git Worktree Helpers ──────────────────────────────────────────
# Commands:
# gwtr — list worktrees sorted by last modified
# cdwt — fzf picker to cd into a worktree
# cdwt <path> — cd directly with tab-completion
# gwtb — jump back to previous worktree
# ── 1. List worktrees sorted by date modified (most recent first) ──
gwtr() {
git worktree list --porcelain \
| awk '/^worktree /{path=$2} /^HEAD /{head=$2} /^branch /{branch=$2; print path, head, branch}' \
| while read -r wtdir head branch; do
# Use wtdir, not path: zsh ties `path` to PATH; read into path breaks stat(1).
modified=$(stat -f "%m" "$wtdir" 2>/dev/null || stat -c "%Y" "$wtdir" 2>/dev/null)
date_fmt=$(stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$wtdir" 2>/dev/null \
|| date -d "@$modified" "+%Y-%m-%d %H:%M" 2>/dev/null)
branch_display="${branch:-detached@${head:0:7}}"
# Strip refs/heads/ prefix for cleaner display
branch_display="${branch_display#refs/heads/}"
printf "%s\t%s\t%s\t%s\n" "$modified" "$date_fmt" "$branch_display" "$wtdir"
done \
| sort -rn \
| awk -F'\t' '
BEGIN { printf "%-14s %-30s %s\n", "MODIFIED", "BRANCH", "PATH"
printf "%-14s %-30s %s\n", "──────────────", "──────────────────────────────", "────────────────────────────────" }
{ printf "%-14s %-30s %s\n", $2, $3, $4 }'
}
# ── 2. cd into a worktree — fzf picker or direct path w/ tab-complete ──
_git_worktree_paths() {
local worktrees
worktrees=($(git worktree list --porcelain 2>/dev/null \
| awk '/^worktree /{print $2}'))
_describe 'worktree' worktrees
}
cdwt() {
local selected
if [[ -n "$1" ]]; then
# Direct path passed — tab-complete behaviour
cd "$1"
return
fi
# Interactive fzf picker
selected=$(git worktree list --porcelain 2>/dev/null \
| awk '/^worktree /{path=$2} /^branch /{branch=$2; print branch"\t"path}' \
| column -t -s $'\t' \
| fzf --height=40% --reverse --border \
--preview 'git -C $(echo {} | awk "{print \$NF}") log --oneline -10' \
--prompt="worktree> ")
[[ -z "$selected" ]] && return
local target
target=$(echo "$selected" | awk '{print $NF}')
cd "$target"
}
compdef _git_worktree_paths cdwt
# ── 3. Jump back to the previous worktree (toggle between last two) ──
_GWT_PREV_PATH=""
_GWT_CWD_PATH=""
_gwt_track() {
local current
current="$(git rev-parse --show-toplevel 2>/dev/null)"
[[ -z "$current" ]] && return
if [[ "$current" != "$_GWT_CWD_PATH" ]]; then
_GWT_PREV_PATH="$_GWT_CWD_PATH"
_GWT_CWD_PATH="$current"
fi
}
autoload -Uz add-zsh-hook
add-zsh-hook chpwd _gwt_track
gwtb() {
if [[ -z "$_GWT_PREV_PATH" ]]; then
echo "No previous worktree recorded."
return 1
fi
cd "$_GWT_PREV_PATH"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment