dsh-merging-stacked-prs について
dsh-merging-stacked-prs は、GitHub のネイティブなスタック機能を使って依存関係のあるプルリクエストを取り込むスキルです。スタックの確認、準備状況の検査、マージ実行、事後検証を案内し、PR ごとの個別マージで代用しません。
主な機能
- 01ネイティブスタック機能と構成を確認
- 02PR の作成者、ベース、ヘッド、順序を確認
- 03許可された方法でスタックブランチを更新
- 04レビュー、状態、必須チェックを事前確認
- 05gh stack merge でマージし結果を検証
活用シーン
- 01依存する PR スタック全体を取り込む
- 02明示した範囲までのスタックをマージ
- 03トランクやリポジトリ規則に応じてブランチを更新
- 04一部マージ後に残りの PR を検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ deepseek-ai/ deepseek-harness --skill dsh-merging-stacked-prsインストール後、Claude Code で/dsh-merging-stacked-prsを入力して読み込まれたか確認します。
詳細
公式 GitHub PR スタックをマージする
依存関係のある PR は、GitHub ネイティブのスタックオブジェクトと gh stack merge を使ってマージします。gh pr merge と gh pr edit を使って個別の PR をマージしたり、ベースブランチを変更したりして、スタックの動作を再現してはいけません。許可されるマージフォワードとリベースの履歴はルートの AGENTS.md に、レビュー修正の反映方法は スタックレビューガイド に記載されています。
ネイティブスタックのサポートを必須とする
GitHub の状態を変更する前に gh stack --version を実行します。公式拡張機能またはサーバー側のスタック機能を利用できない場合は、そこで処理を中止してください。PR を 1 つずつ手動でマージし、ベースブランチを変更する方法に切り替えてはいけません。GitHub スタックでは、すべてのヘッドブランチが同じリポジトリに存在する必要があるため、フォークをまたぐチェーンの場合は処理を中止します。
専用のクリーンなワークツリーを使用します。ブランチ名や以前の報告を信用せず、最新の PR メタデータと正確なヘッド OID を取得します。
gh pr view <pr> --json number,author,baseRefName,baseRefOid,headRefName,headRefOid,isCrossRepository,state,isDraft,reviewDecision,mergeStateStatus,statusCheckRollup
見かけ上の各チェーンから少なくとも 1 つの PR について、PullRequest.stack と stackEntry.position を照会します。ベースブランチからの推測だけではなく、この公式 GitHub オブジェクトをスタックメンバーシップの判断基準にします。size が返されたページ数を超える場合は、entries をページネーションします。
gh api graphql -F owner=<owner> -F name=<repo> -F number=<pr> -f query='
query($owner: String!, $name: String!, $number: Int!) {
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
number
author { login }
baseRefName
headRefName
stackEntry { position }
stack {
number
baseRefName
size
entries(first: 100) {
nodes {
position
pullRequest { number author { login } baseRefName headRefName state isDraft }
}
}
}
}
}
}'
最新の PR ベースから、期待される下から上への順序を確定します。最下位は trunk を対象とし、その上の各 PR は直下の PR のヘッドブランチを対象とします。
不足しているスタックメンバーをリンクする
まず、既存のスタックエントリーと期待されるチェーンを比較します。既存のスタックに、要求されたチェーンの順序を保つ部分集合が含まれている場合があります。スタック番号が複数ある場合、予期しないエントリーがある場合、または順序が競合する場合は、変更を加える前にユーザーに指示を求めます。
依存関係のある PR が公式スタックにまだ含まれていない場合は、次の手順に従います。
- すべての
author.loginを正確に比較します。 - すべての作成者が一致する場合は、下から上への順序でチェーンを自動的にリンクします。
gh stack link --base <trunk> <bottom-pr> <next-pr> ... <top-pr>
- 作成者が異なる場合や、作成者情報を取得できない場合は、GitHub の状態を変更する前にリンクしてよいかユーザーに確認します。
- GraphQL を再照会し、スタック番号が 1 つであること、期待される trunk、PR の完全なセット、期待される位置とベースチェーンを必須条件として確認します。
既存のスタックを自動的に解除、並べ替え、再構築してはいけません。gh stack link は追加のみを行うコマンドであり、マージ済みまたはキューに入ったエントリーはスタックから解除できません。
必要な場合にのみ更新する
更新手段があるという理由だけで、ブランチを書き換えてはいけません。最新のマージ状態またはリポジトリのルールにより trunk の更新が必要な場合は、許可された次のいずれかの履歴を選びます。
- ネイティブのカスケードリベース: リモートスタックがローカルで追跡されていない場合は、
gh stack checkout <pr-or-stack>でチェックアウトしてから、gh stack syncを実行します。このコマンドは、ローカルでの検証前に、アクティブなすべてのレイヤーをリベースし、リース保護付きの強制プッシュを実行する場合があります。書き換えられた範囲を直ちに確認し、影響を受けるすべてのレイヤーについて関連するチェックを実行してください。チェックに合格するまではマージしたり、準備完了を宣言したりしてはいけません。sync でリベースの競合が検出された場合は、gh stack rebaseを使用し、競合を解決して検証してから、gh stack pushで公開します。checkout または sync でローカルとリモートのスタック構成の相違が報告された場合は、処理を中止してユーザーに確認します。リモートスタックを自動的に削除したり、再作成したりしてはいけません。 - 増分マージフォワード: trunk を影響を受ける最下位のブランチにマージし、その後、更新された各親ブランチを下から上への順序で子ブランチに反映して、通常の方法でプッシュします。進行中のマージ中にベースが更新された場合は、新しい先端をマージする前に、その時点の状態を保存します。
レビュー後は、どのような履歴の書き換えも許可されますが、コミット OID に関する前提は無効になります。プッシュ後に正確なヘッドを再取得し、未解決のレビューコメント、承認、マージ可能性、チェックを再監査します。生の --force を使ったり、同時に進んだリモートヘッドを上書きしたりしてはいけません。
マージ範囲の事前確認
マージの直前に、公式スタックを再照会します。選択したすべての PR がオープンで、ドラフトではなく、想定どおりの順序に並び、リポジトリのレビュー要件とチェック要件を満たしていることを確認します。各 PR の状態は個別に扱います。最上位レイヤーの準備ができていても、依存先の準備ができているとは限りません。
「スタックを取り込む」はスタック全体を選択します。一部だけを取り込む場合は、境界となる PR を明示し、最下位からその境界までのすべてのレイヤーを含める必要があります。
スタック API を使ってマージする
公式のスタック番号を指定して、スタック全体をマージします。
gh stack merge <stack-number> --yes --merge
一部だけを取り込むよう明示的に依頼された場合は、境界となる PR までをマージします。
gh stack merge <boundary-pr> --yes --merge
--delete-branch を渡したり、依存する PR のベースブランチを手動で変更したり、PR ごとにマージコマンドを実行したりしないでください。GitHub は選択した範囲を下から順にマージし、残りの上位レイヤーのベースブランチを変更してリベースします。スタックを直接マージする処理は一括で行われます。トランクでマージキューを使用している場合、GitHub は選択した範囲をまとめてキューに入れますが、複数のグループに分けてマージすることがあります。
マージ要件を回避しないでください。ネイティブのマージ処理でブロッカーが報告された場合は、該当する PR を通じて確認・解決するか、停止して報告してください。gh pr merge に切り替えてはいけません。
マージ済みの状態を確認する
選択したすべての PR が MERGED と報告するまで待ちます。キューに入ったリクエストは、マージ完了を意味しません。
gh pr view <pr> --json number,state,mergedAt,mergeCommit,baseRefName,headRefName
一部だけを取り込んだ場合は、公式スタックを再照会し、残っているすべての PR が想定どおりの順序でリンクされ、スタックのトランクまたは直下のレイヤーをベースブランチにしていることを確認します。GitHub が残りのレイヤーをリベースしている可能性があるため、最新のヘッド、レビュー状態、CI も再確認します。
ブランチの削除は、対応する PR が MERGED と報告された後、別の最終工程としてのみ行います。各ブランチを削除する前に、GitHub 上で、そのブランチをベースブランチとして使用しているオープン PR がないことを確認します。
gh pr list --state open --base <branch> --json number --jq length
0 以外の場合は削除できません。
チェックリスト
- ネイティブの
gh stackサポートが利用可能で、すべての PR ブランチが同じリポジトリにあります。 - ライブ PR のベースブランチと正確なヘッドから、下から上へ連なる依存チェーンが 1 つ確定しています。
- GraphQL が、想定されるトランク、エントリー、順序を持つ公式スタックを 1 つ報告しています。条件を満たす、同一作者による未スタックのチェーンは自動的にリンクされています。
- 書き換えられたレイヤーに必要な検証が実施され、その後、レビューのスレッド、承認、マージ可能性、チェックが再監査されています。
- スタック全体、または境界を明示した先頭からの範囲が、
gh stack merge --yes --mergeを通じて送信されています。 - 選択したすべての PR が
MERGEDと報告しています。残りの上位レイヤーがある場合、それらは引き続き想定どおりの公式スタックを構成しています。 - ブランチは、マージ済みの状態と依存する PR がないことを確認した後にのみ削除されています。