| name | merge |
| description | PRをMerge commit方式でマージし、リモート・ローカル両方のfeatureブランチを削除して司令塔ベースブランチを最新化する。マージのタイミングはユーザーが決める。 |
| when_to_use | PRをマージしたい時、「マージして」「merge」「このPRマージ」などの発言時、PR番号を指定してマージを依頼された時。上流の実装ワークフローで pr-review 完了後にマージを選んだ時もこれを実行する。 |
PRマージ
引数: $ARGUMENTS(PR番号。例: 123)
このスキルでは、PRのベースブランチを「ベースブランチ」と呼ぶ(統合ブランチにPRを積む運用ならその統合ブランチ、
単純運用ならデフォルトブランチ)。司令塔はこのベースブランチにいる前提。
前提条件
手順
1. マージ前チェック
gh pr view $ARGUMENTS --json number,title,headRefName,baseRefName,state,mergeable,mergeStateStatus
state が OPEN であること。MERGED / CLOSED なら、その旨を報告して停止(既にマージ済みなら 4 のローカル後片付けだけ実施するか確認する)。
baseRefName が想定どおりのベースブランチであること。想定外のベースなら、勝手にマージせずユーザーに確認する。
mergeable が MERGEABLE であること。CONFLICTING ならコンフリクト解消が必要な旨を報告して停止(このスキルではコンフリクトを解消しない)。
headRefName(= マージ対象の feature/bugfix ブランチ名)を控えておく。4 のローカル削除で使う。
1-1. CI 完了の見届けと合否判定(全チェック成功が必須)
CI の完了を --watch で見届ける。
gh pr checks $ARGUMENTS --watch --interval 30
--watch は全チェックが完了するまでブロックして待ち、完了したら結果を表示して終了する。
実行中(pending)のチェックがあっても、それが終わるまで待ってから合否を判定できる。
--interval 30 は30秒間隔でポーリング(CI が長い場合は適宜伸ばしてよい)。
- なぜ
--watch か:
mergeable: MERGEABLE は「コンフリクトが無い」ことしか保証せず、CI の合否は別物。
コンフリクトが無くても CI が実行中・失敗中のままマージできてしまうため、ここで必ずガードする。
- 「pending なら即停止」だとユーザーが何度も
/merge を叩き直す必要があり手間。--watch は
完了したら必ず抜けるので「待ち続けて止まれない」事故にはならず、見届けと安全停止を両立できる。
- 判定(
--watch 完了後): gh pr checks は全チェック成功なら終了コード 0、1つでも失敗・キャンセルがあれば非0で返る。
- 終了コード 0(全チェック pass / SUCCESS) → 2 へ進みマージする。
- 非0(fail / FAILURE / CANCELLED / TIMED_OUT 等がある) → マージせず停止。
失敗したチェック名を挙げて報告する。原因修正は別途ユーザー判断に委ねる。
--watch の打ち切り目安: CI が異常に長い・ハングしている場合は、無限に待たず適当な時点で打ち切り、
「CI が想定より長くかかっている」と状況を報告してユーザーの判断を仰ぐ。
- ステータスチェックが1つも設定されていない PR(CI 未設定リポジトリ等)の場合は、このガードをスキップしてよい
(
--watch は即座に返る)。
2. マージ実行(Merge commit 方式 + リモートブランチ削除)
gh pr merge $ARGUMENTS --merge --delete-branch
- なぜ
--merge(Merge commit)か: feature の個々のコミットをベースブランチの履歴の鎖に残し、
git checkout <コミットID> での断面復元や git bisect を可能にするため。Squash は中間コミットへの
到達性を構造的に捨てるため採用しない。
--delete-branch でリモートの feature ブランチを削除する。
- gh のバージョンによっては
--delete-branch がローカルブランチも削除しようとするが、
司令塔は別ブランチ(ベースブランチ)にいるため、ローカル feature ブランチが残ることがある。
そのため 4 で明示的にローカル削除を行う(gh 任せにしない)。
2-1. 対応Issueのクローズ
なぜスキル側で明示的にクローズするか: PRのベースがデフォルトブランチでない場合、
GitHub の自動クローズキーワード(Closes #N 等)はデフォルトブランチをターゲットにしたPRでのみ機能するため、
ベースブランチへのマージでは Issue が自動クローズされず取りこぼす。マージの単一窓口である /merge で確実にクローズする。
-
PR本文と headRefName から Issue 番号を抽出する。
gh pr view $ARGUMENTS --json body,headRefName
- 第1優先(PR本文のキーワード): PR本文(
body)から Closes #N / Fixes #N / Resolves #N
(大文字小文字問わず、closes: のようなコロンも許容)にマッチする #N をすべて抽出する。複数あれば全て対象。
- フォールバック(ブランチ名): 本文にキーワードが無い場合、
headRefName(例: feature/123-xxx /
bugfix/45-yyy)の先頭付近の数値を Issue 番号とみなす。feature/ bugfix/ 等のプレフィックス直後の数値を拾う。
-
抽出した各 Issue について、open かどうかを確認してからクローズする。
gh issue view <N> --json number,state,title
gh issue close <N> --comment "PR #$ARGUMENTS のマージに伴いクローズ"
- 既に
CLOSED の Issue はスキップする(再クローズしない)。
- 該当 Issue が存在しない(
gh issue view が 404)場合は、勝手に他の番号を推測せず、その旨を報告する。
-
Issue 番号が1件も抽出できなかった場合: 推測でクローズしてはならない。
「PR本文・ブランチ名から対応 Issue 番号を特定できませんでした。手動でクローズするか、Issue 番号を教えてください」と報告し、
マージ自体(2 まで)は成功している旨も併せて伝える。クローズ失敗で手順全体を止めない(3 以降は続行する)。
3. 司令塔ベースブランチを最新化
git pull --ff-only origin <ベースブランチ名>
- マージ結果(マージコミット)を司令塔のローカルベースブランチに取り込み、リモートと一致させる。
--ff-only が失敗する場合は、勝手に rebase / merge せず状況をユーザーに報告して指示を仰ぐ。
4. ローカル feature ブランチの削除
1 で控えた headRefName(マージ対象ブランチ名)をローカルから削除する。
git branch -d <headRefName>
-d(小文字)を使う: マージ済みでないと削除を拒否する安全側の動作。3 でベースブランチを最新化済みなので、
正常にマージされていれば -d で削除できる。
-d が「not fully merged」で失敗した場合は、-D(強制削除)に勝手に切り替えない。
未マージのコミットが残っている可能性があるため、状況をユーザーに報告して判断を仰ぐ。
- 対象ブランチのローカル worktree が残っている場合(通常は上流の実装ワークフロー内で撤去済み)は、
先に
git worktree remove してからブランチ削除する。
5. リモート追跡参照の掃除(任意)
git fetch --prune origin
- 削除済みリモートブランチへの追跡参照(
origin/feature/...)をローカルから掃除する。
6. 完了報告
以下を報告する:
- マージしたPR番号・タイトル・URL
- マージ方式(Merge commit)
- クローズした対応Issue番号(特定できなかった場合はその旨)
- 削除したブランチ(リモート / ローカルの両方)
- 司令塔ベースブランチの最新化結果(最新コミットハッシュ)
- 異常があった場合はその内容と、ユーザーに委ねた判断
禁止事項
state が OPEN でない、または mergeable が MERGEABLE でないPRを勝手にマージすること
- CI チェックが失敗のままマージすること(
--watch で完了を見届け、全チェック成功を必須とする。1-1 参照)
- ベースブランチが想定外のPRをユーザー確認なしにマージすること
- ローカルブランチ削除で
-d が失敗した際に -D へ勝手に切り替えること
- コンフリクトをこのスキル内で勝手に解消すること
- 対応Issue番号を特定できないのに、推測で Issue を
gh issue close すること(特定不能なら報告して手動対応に委ねる。2-1 参照)