Claude Code Plugins

Community-maintained marketplace

Feedback

Merge GitHub pull requests using gh CLI. Supports merge, squash, and rebase strategies with auto-merge option. Use when PR is approved and ready to merge.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name gh-pr-merge
description Merge GitHub pull requests using gh CLI. Supports merge, squash, and rebase strategies with auto-merge option. Use when PR is approved and ready to merge.
allowed-tools Bash, Read, Grep
handoffs [object Object]

GitHub PR Merge Skill

Merge approved pull requests using the gh CLI with intelligent merge strategies.

When to Use

  • User says "merge the PR" or "merge this pull request"
  • PR is approved and ready to merge
  • User wants to enable auto-merge
  • After all CI checks pass and reviews are approved
  • User wants to merge with specific strategy (squash/rebase)

Prerequisites

Verify GitHub CLI is installed and authenticated:

gh --version
gh auth status

Verify merge permissions:

gh repo view --json viewerPermission --jq '.viewerPermission'
# Should be: WRITE, MAINTAIN, or ADMIN

Execution Workflow

Step 1: Pre-Merge Validation

Before merging, verify the PR is ready:

# Get PR status
gh pr view 123 --json \
  state,isDraft,mergeable,reviewDecision,\
  statusCheckRollup,commits

# Check if:
# - state == "OPEN"
# - isDraft == false
# - mergeable == "MERGEABLE"
# - reviewDecision == "APPROVED" (if required)
# - statusCheckRollup shows all required checks passed

Validation Checklist:

  • PR is open (not closed/merged)
  • PR is not a draft
  • No merge conflicts
  • Required reviews approved
  • All required CI checks passed
  • No blocking conversations

Step 2: Choose Merge Strategy

Determine merge strategy based on:

  • Repository settings
  • Team conventions
  • PR characteristics

Merge Strategies:

  1. Merge Commit (--merge):

    • Preserves all commits and history
    • Creates merge commit
    • Use for: Feature branches with meaningful commit history
  2. Squash and Merge (--squash):

    • Combines all commits into one
    • Clean linear history
    • Use for: Feature PRs with many WIP commits
  3. Rebase and Merge (--rebase):

    • Replays commits on base branch
    • No merge commit
    • Use for: Clean commit history, linear timeline

Auto-detect strategy:

# Check repository default merge method
MERGE_METHOD=$(gh api repos/:owner/:repo --jq '
  if .allow_squash_merge and .allow_merge_commit and .allow_rebase_merge then
    "ask"
  elif .allow_squash_merge then
    "squash"
  elif .allow_rebase_merge then
    "rebase"
  elif .allow_merge_commit then
    "merge"
  else
    "error"
  end
')

Step 3: Merge the PR

Standard merge:

gh pr merge 123 --squash

With custom commit message:

gh pr merge 123 --squash \
  --subject "Add user authentication" \
  --body "$(cat <<'EOF'
Implements JWT-based authentication with:
- Login/logout endpoints
- Token refresh mechanism
- Password hashing with bcrypt
- Session management

Closes #45
EOF
)"

Auto-merge (merge when checks pass):

gh pr merge 123 --auto --squash

Delete branch after merge:

gh pr merge 123 --squash --delete-branch

Admin merge (bypass protections):

gh pr merge 123 --squash --admin
# ⚠️ Use with extreme caution!

Step 4: Verify Merge

After merging, confirm success:

# Check PR status
gh pr view 123 --json state,merged,mergedAt

# Verify base branch updated
git fetch origin
git log origin/main -1 --oneline

# Check if branch deleted
gh api repos/:owner/:repo/branches/feature-name 2>&1 | grep -q "Not Found"

Step 5: Report Success

Present merge result:

✓ PR #123 merged successfully

Strategy: Squash and merge
Merged by: @username
Merged at: 2024-01-01 15:30:00
Branch deleted: Yes

Commit: abc1234 - "Add user authentication"
Base branch: main updated

🔗 [View merged PR](https://github.com/owner/repo/pull/123)

Common Scenarios

Scenario 1: Simple Squash Merge

# Verify PR is ready
gh pr view 123 --json reviewDecision,mergeable
# reviewDecision: "APPROVED", mergeable: "MERGEABLE"

# Check CI
gh pr checks 123
# All checks passed ✓

# Merge with squash
gh pr merge 123 --squash --delete-branch

echo "✓ PR #123 merged and branch deleted"

Scenario 2: Auto-Merge When Checks Pass

# Enable auto-merge for approved PR waiting on CI
gh pr merge 123 --auto --squash

echo "⏳ Auto-merge enabled. PR will merge when all checks pass."

# Watch check progress
gh pr checks 123 --watch

Scenario 3: Merge with Custom Message

# Merge with detailed commit message
gh pr merge 123 --squash \
  --subject "feat: add user authentication system" \
  --body "$(cat <<'EOF'
Implements comprehensive authentication:

Features:
- JWT token-based auth
- Secure password hashing
- Session management
- OAuth2 integration

Breaking Changes:
- Auth header format changed from Bearer to JWT

Migration Guide:
Update client auth headers to use new JWT format.

Closes #45, #67
Related: #23

Co-authored-by: Alice <alice@example.com>
Co-authored-by: Bob <bob@example.com>
EOF
)"

Scenario 4: Merge with Rebase for Clean History

# For PRs with clean, meaningful commits
gh pr view 123 --json commits

# Verify each commit is good
gh pr view 123 --json commits \
  | jq -r '.commits[] | .messageHeadline'

# Merge with rebase to preserve commits
gh pr merge 123 --rebase --delete-branch

Scenario 5: Conditional Merge Based on Checks

# Only merge if all conditions met
PR_NUM=123

# Get PR data
PR_DATA=$(gh pr view $PR_NUM --json \
  reviewDecision,mergeable,statusCheckRollup,isDraft)

REVIEW=$(echo "$PR_DATA" | jq -r '.reviewDecision')
MERGEABLE=$(echo "$PR_DATA" | jq -r '.mergeable')
IS_DRAFT=$(echo "$PR_DATA" | jq -r '.isDraft')
CHECKS=$(echo "$PR_DATA" | jq -r '.statusCheckRollup[] | select(.isRequired == true) | .conclusion')

# Validate
if [[ "$REVIEW" == "APPROVED" ]] && \
   [[ "$MERGEABLE" == "MERGEABLE" ]] && \
   [[ "$IS_DRAFT" == "false" ]] && \
   ! echo "$CHECKS" | grep -qv "SUCCESS"; then

  gh pr merge $PR_NUM --squash --delete-branch
  echo "✓ PR merged successfully"
else
  echo "⚠ PR not ready to merge:"
  echo "  Review: $REVIEW"
  echo "  Mergeable: $MERGEABLE"
  echo "  Draft: $IS_DRAFT"
  echo "  Checks: $CHECKS"
  exit 1
fi

Scenario 6: Batch Merge Approved PRs

# Merge all approved PRs from a milestone
gh pr list --json number,reviewDecision,mergeable,milestone \
  | jq -r '.[] |
    select(.reviewDecision == "APPROVED") |
    select(.mergeable == "MERGEABLE") |
    select(.milestone.title == "v1.0") |
    .number' \
  | while read pr; do
    echo "Merging PR #$pr..."
    gh pr merge $pr --squash --delete-branch
    sleep 2  # Rate limiting
  done

Advanced Options

Merge Queue

For repositories with merge queues enabled:

# Add to merge queue
gh pr merge 123 --auto --squash

# Check queue position
gh api repos/:owner/:repo/pulls/123/merge_queue \
  | jq '.position'

Protected Branch Bypass

For admin users only:

# Bypass branch protections (use with extreme caution)
gh pr merge 123 --admin --squash

# This bypasses:
# - Required reviews
# - Status checks
# - Restrictions

Merge with Required Linear History

# For repos requiring linear history
gh pr merge 123 --rebase

# Or squash to maintain linearity
gh pr merge 123 --squash

Merge Dependabot PRs

# Auto-merge approved Dependabot PRs
gh pr list --author app/dependabot \
  --json number,reviewDecision \
  | jq -r '.[] | select(.reviewDecision == "APPROVED") | .number' \
  | while read pr; do
    gh pr merge $pr --auto --squash --delete-branch
  done

Error Handling

Error: "Pull request is not mergeable"

  • Cause: Merge conflicts exist
  • Solution: Resolve conflicts first
git fetch origin
git checkout feature-branch
git merge origin/main
# Resolve conflicts
git push

Error: "Required status checks have not succeeded"

  • Cause: CI checks failing or pending
  • Solution: Wait for checks or fix failures
gh pr checks 123 --watch

Error: "Review required"

  • Cause: PR needs approval
  • Solution: Request reviews
gh pr review 123 --approve
# Or request from others:
gh pr edit 123 --add-reviewer user1,user2

Error: "Branch protection rule violations"

  • Cause: Branch protections not met
  • Solution: Satisfy requirements or use admin override (if authorized)

Error: "Pull request is closed"

  • Cause: PR already merged or closed
  • Solution: Verify PR status
gh pr view 123 --json state,merged

Error: "Auto-merge not allowed"

  • Cause: Repository doesn't have auto-merge enabled
  • Solution: Use standard merge or enable in repository settings

Best Practices

  1. Always validate first: Check reviews, checks, and mergeable status
  2. Choose appropriate strategy:
    • Squash for feature branches with messy history
    • Rebase for clean commits
    • Merge for preserving exact history
  3. Delete branches: Use --delete-branch to clean up
  4. Write good merge messages: Provide context for squash merges
  5. Use auto-merge for trusted PRs: Let CI complete before merging
  6. Never force merge: Avoid --admin unless absolutely necessary
  7. Verify after merge: Check base branch was updated
  8. Follow team conventions: Use team's preferred merge strategy
  9. Wait for required checks: Don't bypass failing checks
  10. Review before merge: One final check of the code

Merge Strategy Decision Tree

Is commit history clean and meaningful?
├─ Yes → Use --rebase
└─ No
   ├─ Multiple WIP commits? → Use --squash
   └─ Want to preserve exact history? → Use --merge

Does repository require linear history?
├─ Yes → Use --squash or --rebase
└─ No → Any strategy works

Is this a hotfix or emergency?
├─ Yes → Use --merge (preserve all context)
└─ No → Follow normal team conventions

Related Skills

  • gh-pr-view - View PR details before merging
  • gh-pr-create - Create pull requests
  • gh-pr-review - Review and approve PRs
  • gh-pr-ready - Mark draft as ready

Limitations

  • Requires write access to repository
  • Cannot merge if branch protections not satisfied (without admin override)
  • Auto-merge requires repository setting enabled
  • Squash merge may lose commit-level context
  • Rebase may cause issues with force-pushed branches

See Also