Skip to content

Instantly share code, notes, and snippets.

@zanieb
Created January 15, 2026 16:07
Show Gist options
  • Select an option

  • Save zanieb/1a0159a30d8550adeabeef977fbc85b2 to your computer and use it in GitHub Desktop.

Select an option

Save zanieb/1a0159a30d8550adeabeef977fbc85b2 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# gco <branch> - Switch to branch in current directory
# If branch has a worktree elsewhere, remove it first (requires clean state)
set -eu
NAME=${1:-}
shift || true
REST="$*"
if [ -z "$NAME" ]; then
echo "Usage: gco <branch> [git-checkout args]" >&2
exit 1
fi
# Pass-through mode for file checkout
if [ -n "$REST" ]; then
git checkout "$NAME" $REST
exit 0
fi
# Check for existing worktree
WORKTREE_PATH=$(git worktree list | rg -v "prunable" | rg "\[$NAME\]" | cut -d' ' -f1)
if [ -n "$WORKTREE_PATH" ] && [ -d "$WORKTREE_PATH" ]; then
if [ "$PWD" = "$WORKTREE_PATH" ]; then
echo "Already in worktree for $NAME"
exit 0
fi
# Check worktree is clean before removing (ignore untracked files)
if [ -n "$(git -C "$WORKTREE_PATH" status --porcelain | grep -v '^??')" ]; then
echo "Error: Worktree at '$WORKTREE_PATH' has uncommitted changes" >&2
exit 1
fi
# Check current directory is clean (ignore untracked files)
if [ -n "$(git status --porcelain | grep -v '^??')" ]; then
echo "Error: Current directory has uncommitted changes" >&2
exit 1
fi
echo "Removing worktree at $WORKTREE_PATH"
git worktree remove "$WORKTREE_PATH"
elif [ -n "$WORKTREE_PATH" ]; then
# Stale worktree entry
git worktree remove --force "$WORKTREE_PATH"
fi
# Switch or create branch
if git branch -la | rg -q "^\s*($NAME|remotes/.*/$NAME)$"; then
git switch "$NAME"
else
git switch -c "$NAME"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment