Skip to content

Instantly share code, notes, and snippets.

@mikker
Last active July 9, 2025 21:32
Show Gist options
  • Save mikker/8b77136672ec3f493b0c46b10218cea7 to your computer and use it in GitHub Desktop.
Save mikker/8b77136672ec3f493b0c46b10218cea7 to your computer and use it in GitHub Desktop.
Start a new git worktree in tmux
#!/usr/bin/env bash
set -euo pipefail
issue=$1
~/.claude/local/claude \
"Start working on issue #$issue
- Keep an open mind. Feel free to reconsider the proposed approach
- Use context7 for updated docs
- Don't go out of your way to keep everything backwards compatible. Rather investigate if we can change things once and for all
- Update the issue as you discover new relevant information, make progress or decisions
- After you're done, read through your changes and see if there are things that can be simplified and remove any unused code or obsolete code paths
- Finally, make a PR with your changes. If one exists for this issue, update it. Include progress made" \
--allowedTools "Edit" "Write" "Read" \
"Bash(gh:*)" "Bash(rg:*)" "Bash(find:*)" "Bash(ls:*)" "Bash(grep:*)" "context7:*" \
"Bash(bin/format:*)" "Bash(bin/check:*)" \
"Bash(bin/rails:*)" \
"Bash(git:*)"
#!/usr/bin/env bash
# gwt — “git worktree in tmux”
# ▸ gwt NAME → create/reuse worktrees/NAME
# ▸ gwt → pick an existing work-tree with fzf
set -euo pipefail
################################################################################
# 0 · ensure we’re inside a Git repo and move to its root
################################################################################
root=$(git -C . rev-parse --show-toplevel 2>/dev/null) || {
echo "gwt: not inside a Git repository" >&2
exit 1
}
cd "$root"
mkdir -p worktrees/ # folder that holds our work-trees
################################################################################
# 1 · pick/create the work-tree
################################################################################
if [[ $# -eq 0 ]]; then
# interactive *pick* via fzf
command -v fzf >/dev/null 2>&1 || {
echo "gwt: fzf not found (needed for interactive selection)" >&2
exit 1
}
# list all work-tree paths (absolute) and feed them to fzf
wtdir=$(git worktree list --porcelain |
awk '/^worktree / {print $2}' |
fzf --prompt='Worktree ❯ ' --exit-0)
[[ -n ${wtdir:-} ]] || exit 0 # user pressed <Esc>
name=$(basename "$wtdir") # eg. worktrees/feature → feature
else
# create/reuse worktrees/NAME
name=$1
wtdir="$root/worktrees/$name"
fi
window="$name" # tmux window name
session="worktrees" # tmux session that herds all work-trees
################################################################################
# 2 · figure out the repo’s default branch for *new* work-trees
################################################################################
if git branch --format='%(refname:short)' | grep -q '^master$'; then
main_branch=master
else
main_branch=main
fi
################################################################################
# 3 · one shared snippet we’ll send to tmux
################################################################################
setup_worktree=$(
cat <<EOF
cd "$root"
if [ -d "$wtdir/.git" ]; then
cd "$wtdir"
else
git worktree add -b "$name" "$wtdir" $main_branch
cd "$wtdir"
fi
exec \$SHELL
EOF
)
################################################################################
# 4 · inside-tmux vs. outside-tmux workflow
################################################################################
if [[ -n ${TMUX:-} ]]; then
tmux rename-window "$window"
tmux send-keys "$setup_worktree" C-m
exit 0
fi
tmux new-session -Ad -s "$session" -n "$window"
if tmux list-windows -t "$session" -F '#{window_name}' | grep -Fxq "$window"; then
tmux select-window -t "$session:$window"
else
tmux new-window -t "$session" -n "$window"
fi
tmux send-keys -t "$session:$window" "$setup_worktree" C-m
tmux attach -t "$session:$window"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment