# Pr Merge

> Use when the user asks to merge or land a pull request, or says "ship it" for an already-reviewed PR.

- Skill: `mia-cx/pr-merge` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mia-cx/pr-merge`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mia-cx/pr-merge/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: mia-cx (https://skillmd.com/u/mia-cx)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mia-cx/pr-merge

---


# Merge a pull request

Read the PR, post a flavourful comment, merge with a clean subject, close its linked issues, fast-forward the local base branch.

The user's request to merge is authoritative confirmation that required human validation is complete. Do not leave the PR or a linked issue open because a validation checkbox or comment was not separately updated first.

## Workflow

### 1. Identify and read the PR

- Use the provided PR number/URL; otherwise `gh pr list --state open` and pick the obvious one (ask only if genuinely ambiguous).
- `gh pr view <number> --json title,body,headRefName,baseRefName,commits,files,reviews,comments,labels,milestone` and `gh pr diff <number>` to understand what the PR actually delivers.
- Record every open issue directly referenced by the PR body or commits (`#N`, `Fixes #N`, `Closes #N`) for closing after the merge. Do not recursively close parent, dependency, or related issues mentioned only inside those linked issues.

### 2. Check merge readiness

- CI passing: `gh pr checks <number>`
- Required approvals present (`reviews` from step 1)
- No conflicts: `gh pr view <number> --json mergeable`

If the PR is not ready, report the blockers and stop. Do not merge a PR that isn't green.

### 3. Retarget any stacked children first

Before merging, find open PRs whose base is *this* PR's head branch:

```bash
head="$(gh pr view <number> --json headRefName --jq '.headRefName')"
gh pr list --state open --json number,baseRefName \
  --jq ".[] | select(.baseRefName == \"$head\") | .number"
```

Retarget each onto this PR's base **before** the merge:

```bash
gh api -X PATCH repos/{owner}/{repo}/pulls/<child> -f base="$base"
```

Do not skip this and rely on GitHub retargeting them for you. Deleting a branch that is still the
base of an open PR **closes that PR**, and the recovery is awkward: a closed PR cannot be retargeted,
and it cannot be reopened while its base branch is missing. You have to push the deleted branch
back, reopen, retarget, then delete it again. GitHub's own retarget-on-merge does not reliably beat
the branch deletion to it.

`gh pr edit --base` is the obvious command and it fails on repos with Projects (classic) enabled, so
prefer the REST call above.

### 4. Post the flavour comment

Before merging, post the narrative as a PR comment so it lives in GitHub's timeline:

```bash
gh pr comment <number> --body "<flavour body>"
```

Summarize the PR's impact with the personality of a senior dev proud of what the team shipped. Dry wit, a pun, a lyric, a mini-poem, a metaphor are all fair game, and the substance (what it delivers, key decisions, anything to watch) always comes through.

This comment is a sanctioned flavour zone: it overrides global style rules that ban idioms, metaphors, and wordplay, on purpose.

**feat:**
> *"We're not in Kansas anymore"*, and neither is the dashboard. Ships the analytics overview: real-time charts, filterable date ranges, and an export button that actually works.

**fix:**
> The auth token was expiring mid-request like a carton of milk left on the counter. Added a refresh buffer so tokens get renewed 30 seconds before expiry instead of after the 401 hits.

**chore:**
> *"I fought the deps and the deps won"*. Bumped everything that wasn't pinned, fixed the two breaking changes, and updated the lockfile. CI is green and the audit is clean.

### 5. Merge

Merge immediately after the comment, no approval round-trip:

```bash
gh pr merge <number> --merge --delete-branch --subject "type(scope): short imperative description (#N)"
```

- Subject only, **no body**; the flavour lives in the comment.
- `--delete-branch` matters most in a stack: GitHub retargets a child PR onto the merged base only
  when the head branch is deleted, so keeping it means retargeting every child by hand. Merged
  branches are recoverable from the merge commit, so this costs nothing.
- Under ~72 chars, no trailing period, PR number at the end.
- `--merge` by default; match the repo's convention (`--squash` / `--rebase`) when it has one. Check `gh api repos/{owner}/{repo} --jq '.allow_merge_commit, .allow_squash_merge, .allow_rebase_merge'` if unsure.

### 6. Fast-forward the local base branch

Update the local base (the PR's `baseRefName`, usually `main`) so the repo is ready for the next slice:

```bash
base="$(gh pr view <number> --json baseRefName --jq '.baseRefName')"
git fetch origin "$base"
base_worktree="$(
  git worktree list --porcelain | awk -v branch="refs/heads/$base" '
    /^worktree / { path = substr($0, 10) }
    /^branch / && substr($0, 8) == branch { print path; exit }
  '
)"

if [ -n "$base_worktree" ]; then
  git -C "$base_worktree" pull --ff-only
else
  git fetch origin "$base:$base"
fi
```

If the fast-forward fails because the local base is dirty or diverged, report that the PR merged but the local base needs attention. Do not reset, stash, or discard local work.

### 7. Close linked issues

Close every still-open issue recorded in step 1 as completed, with the completion evidence in the timeline:

```bash
gh issue close <issue-number> --reason completed \
  --comment "Completed by #<pr-number> (<merge-commit>)."
```

Close them whether linked via `Refs`, `Fixes`, or `Closes`. GitHub may have auto-closed some, so skip issues already closed. Only leave a directly linked issue open on explicit user request.

Confirm with a summary like **"PR #N merged and local main fast-forwarded. Another one bites the dust."**

