Skip to content

Instantly share code, notes, and snippets.

@sughodke
Last active January 14, 2026 19:48
Show Gist options
  • Select an option

  • Save sughodke/0ca5a08e045822cb57df0a03890801a1 to your computer and use it in GitHub Desktop.

Select an option

Save sughodke/0ca5a08e045822cb57df0a03890801a1 to your computer and use it in GitHub Desktop.
πŸŽ„ Sync worktrees for your active PRs

You have a bunch of active PRs, and are responding to comments in each.

Well you should really have a worktree for each PR.

Add this alias:

  gh alias set pr-worktrees --shell '
  gh pr list --json number,headRefName,author \
    --jq ".[] | select(.author.login == \"$(gh api user --jq .login)\") | \"\(.number) \(.headRefName)\"" |
  while read -r pr branch; do
    if [ -d "../pr-$pr" ]; then
      echo "Skipping PR #$pr: worktree already exists"
      continue
    fi
    git fetch origin "$branch":"$branch" 2>/dev/null || {
      git fetch origin "$branch" 
      git branch -f "$branch" "origin/$branch" 2>/dev/null
    }
    git worktree add "../pr-$pr" "$branch" 2>&1 || echo "Failed to create worktree for PR #$pr"
  done

Now gh pr-worktrees creates worktrees for your open PRs in ../pr-{number}/.


Once your branches merge, you'll want to do a cleanup, alias this command

  gh alias set pr-worktrees-clean --shell '
  merged=$(gh pr list --state merged --json number,author \
    --jq ".[] | select(.author.login == \"$(gh api user --jq .login)\") | .number")
  for dir in ../pr-*; do
    [ -d "$dir" ] || continue
    pr="${dir##*-}"
    if echo "$merged" | grep -qx "$pr"; then
      branch=$(git worktree list --porcelain | grep -A2 "worktree.*$dir" | grep "branch" | sed "s|branch refs/heads/||")
      echo "Removing merged PR #$pr: $dir"
      git worktree remove "$dir" --force || rm -rf "$dir"
      [ -n "$branch" ] && git branch -D "$branch" 2>/dev/null
    else
      echo "Keeping PR #$pr (not merged)"
    fi
  done
  git worktree prune
  '

Now gh pr-worktrees-clean removes worktrees only for merged PRs


All in one sync command

  gh alias set pr-worktrees-sync --shell '
  user=$(gh api user --jq .login)

  # Clean up merged PRs (only ../pr-* directories)
  merged=$(gh pr list --state merged --json number,author --jq ".[] | select(.author.login == \"$user\") | .number")
  for dir in ../pr-*; do
    [ -d "$dir" ] || continue
    pr="${dir##*-}"
    if echo "$merged" | grep -qx "$pr"; then
      branch=$(git worktree list --porcelain | grep -A2 "worktree.*$dir" | grep "branch" | sed "s|branch refs/heads/||")
      echo "Removing merged PR #$pr: $dir"
      git worktree remove "$dir" --force || rm -rf "$dir"
      [ -n "$branch" ] && git branch -D "$branch" 2>/dev/null
    fi
  done
  git worktree prune

  # Create worktrees - either specific PR or all open PRs
  if [ -n "$1" ]; then
    prs=$(gh pr view "$1" --json number,headRefName --jq "\"\(.number) \(.headRefName)\"")
  else
    prs=$(gh pr list --json number,headRefName,author --jq ".[] | select(.author.login == \"$user\") | \"\(.number) \(.headRefName)\"")
  fi

  echo "$prs" |
  while read -r pr branch; do
    [ -z "$pr" ] && continue
    if [ -d "../pr-$pr" ]; then
      echo "Skipping PR #$pr: worktree already exists"
      continue
    fi
    if git worktree list | grep -q "\[$branch\]"; then
      echo "Skipping PR #$pr: branch $branch already checked out"
      continue
    fi
    git fetch origin "$branch":"$branch" 2>/dev/null || {
      git fetch origin "$branch"
      git branch -f "$branch" "origin/$branch" 2>/dev/null
    }
    git worktree add "../pr-$pr" "$branch" 2>&1 || echo "Failed to create worktree for PR #$pr"
  done
  '
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment