merge-it — merge a ready PR, then wrap up automatically
The active counterpart to post-merge. When I say “merge it”, I mean: do the merge now (the PR is ready), then run the whole post-merge wrap-up (verify → tidy → UMS) on your own, without asking. Asking “want me to run UMS?” after merging is the exact gap this skill closes — the answer is a standing yes (see preferences.md).
When this fires
- “merge it”, “merge this”, “merge the PR”, “go ahead and merge” (as an explicit merge directive). Deliberately excludes vague approval like “ship it” / “lgtm” — merging is irreversible, so require an explicit merge verb.
- Distinct from
merge-main/sync-pr-branch(those mergemaininto a branch to sync it — they do NOT merge the PR). - If the PR is already merged, skip steps 2–3 and go straight to step 4 (
post-merge).
Procedure
1. Identify the PR and confirm it’s ready — never assume
- Resolve which PR is meant (the one from the current session; if ambiguous, ask which number).
- Confirm it is fully clean before merging (the ARDI terminal state — see
shared/workflow/fully-clean.md): every CI workflow and check run — not just required ones — is green and completed (never still queued or in progress) AND the latest review is clean. Verify with a fresh query, not a cached verdict:mcp__github__pull_request_read(getformergeable_state,get_check_runsfor CI) — orgh pr view <N>/gh pr checks <N>in a local session.get_check_runs/gh pr checksonly cover check runs (plus legacy statuses), not every raw Actions workflow run — seefully-clean.md’saction_required-with-zero-jobs gotcha if something looks off despite an all-clear checks view. - Check
mergeStateStatusin addition tomergeable. A PR can be"MERGEABLE"but"BLOCKED"when branch protection requires at least one approving review and only bot/comment reviews exist. Fix: requestd-morrisonas reviewer (gh pr edit <N> --add-reviewer d-morrison—EDIT_PR) and leave a note that the PR is clean and ready. Don’t attempt to force-merge. - If any CI workflow or check run is red or still in progress/queued/pending, or the review still has open findings, do not merge. Report what’s blocking instead. (Only merge a not-clean PR if the user explicitly says to anyway.)
2. Merge
- Default to squash for a feature branch with many small iteration commits (and/or a merge-of-main commit) — it gives
mainone clean commit. Use a plain merge commit only if the user asks or the repo clearly prefers it; don’t stop to ask for a method on a routine feature PR. - Give the squash an accurate commit title and body when the PR body has gone stale across the review loop — pass
commit_title/commit_messagerather than letting GitHub paste the outdated description. KeepCloses #Nin the message so the linked issue auto-closes. - If
gh pr mergefails withHead branch is out of date, first read the PR’s actual base branch (gh pr view <N> --json baseRefName -q .baseRefName— do not assumemain; stacked and release PRs target a different base), sync that base into the PR branch, and retry once. Syncing the base creates a new head SHA, which invalidates the CI/review “fully clean” snapshot that authorized the original merge attempt — re-run the ARDI “fully clean” check (fully-clean.md) against the new SHA before retrying the merge, don’t just retry the merge command itself; a repo that doesn’t make every workflow/review a required branch-protection check can otherwise merge an unreviewed/untested new head. If the merge still fails, don’t compare againstoriginblindly — for a cross-fork PR,originis the base repo, not necessarily where the head branch lives, sogit ls-remote origin refs/heads/<branch>can silently read a missing ref or an unrelated same-named branch in the base repo. Get the actual head repo and ref from the PR API first (gh pr view <N> --json headRepositoryOwner,headRepository,headRefName), then query that repo’s ref (gh api repos/<head-owner>/<head-repo>/git/refs/heads/<head-ref> --jq .object.sha— verified this endpoint works) and compare it against the PR API’s own.head.sha(gh api repos/<owner>/<repo>/pulls/<N> --jq .head.sha) — the PR object can lag the branch ref briefly, so the correct response is to wait until the two agree, not to keep retrying blindly. Only use--adminas a last resort when the user has separately and explicitly authorized the branch-protection bypass itself — ordinary merge authorization does not cover it (seepreferences.md).
# MERGE_PR — remote/web (GitHub MCP):
# mcp__github__merge_pull_request merge_method=squash commit_title=… commit_message=…
# local:
gh pr merge <N> --squash --subject "<title>" --body "<accurate summary; Closes #N>"In remote/web sessions, load the merge tool’s schema with ToolSearch (select:mcp__github__merge_pull_request) before the first call to confirm the exact name and parameters – tool-mappings.md is the canonical gh→MCP reference (per CLAUDE.md’s “Skills that call gh/glab” rule); d-morrison/gha’s own CLAUDE.md carries an equivalent table for that repo.
3. Verify the merge landed — never assume
Confirm merged == true (the merge tool’s result) and re-check the PR state and that the linked issue auto-closed. If the merge didn’t land (conflict, branch protection, not mergeable), stop and report — don’t tidy or run UMS.
4. Chain into post-merge — automatically
Run the post-merge skill (invoke it by name) for the rest: tidy the local branch (checkout main, pull, git branch -d, remove any worktree), confirm deferred items are tracked, and run UMS to bank what the PR’s review lifecycle taught. Do this without a separate prompt — opening the UMS follow-up branch + PR is a standing yes (preferences.md).
Relationship to other skills
post-merge— step 4 delegates to it.post-mergeassumes the PR is already merged (verify → tidy → UMS);merge-itadds the actual merge in front of it for the “it’s clean, merge it” case.merge-main/sync-pr-branch— mergemainINTO a PR branch to sync; unrelated to merging the PR itself. Don’t confuse the trigger words.ardi/iterate— the loop that gets a PR to fully-clean;merge-itis what you run once it’s there and the user says go.ums— the learnings steppost-mergeruns at the end.wrap-up/merged— session-level bookend;merge-itis per-PR.
Anti-patterns
- ❌ Asking “want me to run UMS / wrap up?” after merging — it’s automatic.
- ❌ Reporting the merge as done and moving on (including to other things the user said while the merge was in flight) without actually running step 4 — a busy, multi-threaded conversation makes this easy to drop, but the chain isn’t optional follow-up; it’s part of the merge action itself. See
mwc’s own anti-pattern entry for the concrete case this happened in. - ❌ Merging a PR that isn’t fully clean (red or still-in-progress CI, or open findings) without the user explicitly saying so.
- ❌ Letting the squash commit inherit a stale PR description — pass an accurate title/body when the body no longer matches the final diff.
- ❌ Confusing “merge it” (merge the PR) with “merge main” (sync the branch).
- ❌
git branch -D(force) in the tidy without checking why-drefused.