GitHub stacked pull requestを実際に動かしてみた

GitHub stacked pull requestを実際に動かしてみた

レビュー単位を小さくしながら大きな変更を進められるStaked pull requestの紹介
2026.08.04

こんちには。製造ビジネステクノロジー部の中村( @nokomoro3 )です。

今回はPublic Previewとなった「Stacked pull requests」についてご紹介します。

https://github.blog/changelog/2026-07-30-stacked-pull-requests-are-now-in-public-preview/

今回はこの機能を実際にGitHub上とCLIで試してみたので、その内容をご紹介します。

そもそも何を解決する機能なのか

大規模な変更を1つのPull Requestにまとめると、差分が大きくなりレビューに時間がかかるという問題があります。
一方で変更を複数のPull Requestに分割すると依存するブランチのrebaseやbaseブランチの変更を手作業で管理する必要がありました。

Stacked pull requestsは、依存関係のある複数のPull Requestを、順序を持った1つのスタックとして管理する機能です。

たとえば、1つの機能開発を次のように分割できます。

develop
└─ feature/auth: 認証基盤の修正 (PR1)
    └─ feature/api: APIの修正 (PR2)
        └─ feature/ui: UIの修正 (PR3)

PR2はPR1のブランチをbaseとし、PR3はPR2のブランチをbaseとします。
これにより、それぞれのPull Requestにはそのレイヤーで追加した差分だけが表示されるため、大きな変更を小さく、目的の明確な単位でレビューできます。

主なメリットは次のとおりです。

  • 大規模な変更を、レビューしやすい小さなPull Requestに分割できる
  • 依存関係を保ったまま、複数のPull Requestを並行してレビューできる
  • 各Pull Requestで既存のチェックやブランチ保護ルールを利用できる
  • スタック全体、または下位のPull Requestだけをまとめてマージできる
  • CLIを使って連鎖的なrebaseやPRのbase設定を自動化できる

つまり、Stacked pull requestsは大きな変更を小さなPull Requestに分割しつつ、ブランチ間の依存関係をGitHubに管理してもらうための機能です。

GitHubの公式発表でも、レビュー単位を小さくしながら大きな変更を進められる点が主な目的として紹介されています。

(決して大きなPull Requestをまとめてさらに大きくする機能ではありません!!!)

本記事では、Stacked pull requestsをGitHub上とCLIの両方から実際に操作し、それぞれの機能や基本的なワークフローをご紹介します。

GitHub上でスタックを作成する

以下のようなスタック化したPull Requestがある状態からスタートします。

GitHub上で当該Pull Requestのいずれかを開くと、以下のような画面となります。

Preview stackを押下すると、以下のような画面となります。

Create stackを押下すると、以下のように管理されます。

CLIによるスタック操作

GitHub上での見た目はそこまで変わらないのですが、CLIと組み合わせることで強力な機能が使えます。

インストール

GitHub CLIがインストールされている場合は、以下のように拡張機能をインストールするだけとなります。

gh extension install github/gh-stack

インストール後の確認です。

gh extension list
# NAME      REPO             VERSION
# gh stack  github/gh-stack  v0.1.0

よく使う基本フロー

gh stackコマンドの詳細は後述しますが、以下を基本フローとして押さえておけば良さそうです。

# スタックの1段目を開始(スタック管理の監視)
gh stack init feature/auth

# ベースを指定したい場合は --base オプションを使用
gh stack init --base develop feature/auth

# スタックの2段目、3段目を追加
gh stack add feature/api
gh stack add feature/ui

# 状態確認
gh stack view

# スタックの変更をGitHubへ公開、PRの作成やstackの作成をまとめて行う
gh stack submit

# スタックをローカルとリモートで同期したり、スタック内のブランチ構成を整合させる処理を行う
gh stack sync

# スタックをまとめてマージ
gh stack merge

ローカル側の操作

CLIによるスタック操作について、まずはローカル側の操作コマンドは以下のようになります。

コマンド 役割
init 新しいスタックを作る/既存ブランチをスタックとして登録する
add 現在のスタックの一番上に、新しいブランチを追加する
checkout スタック番号・PR番号などから、そのスタックを取得してチェックアウトする
modify ブランチの並べ替え、名前変更、統合、除外などを対話的に行う
unstack ローカル追跡とGitHub上のスタック関係を解除する
view 現在のスタック、ブランチ、PR状態を表示する

init: スタック管理の開始

init でスタック管理を開始します。

gh stack init feature/auth

複数ブランチの場合、以下でまとめて指定することも可能です。

gh stack init feature/auth feature/api feature/ui

gh stack init では既存ブランチであれば取り込み、同名ブランチが存在しなければ新しいブランチを作成します。

またベースを指定しない場合はデフォルトブランチがベースとなります。
ベースを指定したい場合は --base オプションを使用します。

gh stack init --base develop feature/auth

add: スタック管理への追加

add でスタックの一番上(後続)に新しいブランチを追加します。

gh stack add feature/ui

checkout: スタックのチェックアウト

checkout で別のスタックをローカルに持ってくることができます。

引数を指定しなければ、ローカル/GitHub上のスタックを対話的に選択できます。

gh stack checkout

# Checkout a stack
# All   Local   Remote
# 
# #      Branches                        Base     Status     Type    Created
# › 446  feature/auth...feature/ui       develop  ▆▆▆▆▆   Remote  1h ago
#↑↓ navigate · ←→ tabs · / search · enter select · esc quit

上記の 446 という番号は、既存のpull requestには割り当てられていない番号のようでした。
そのためGitstack用の採番が行われているようです。

引数で指定する場合はstackの番号を指定する必要はなく、いずれかのpull requestの番号を指定すればチェックアウトが可能でした。

gh stack checkout {PRの番号}

modify: スタック構造の変更

modify でスタック構造を対話画面で編集します。

gh stack modify

できることは、ブランチの並べ替え・リネーム・追加・除外・隣接ブランチへの統合などです。
競合が起きた場合は次を使います。

gh stack modify --continue
gh stack modify --abort

編集後、GitHub側にも反映するには gh stack submit が必要です。

unstack: スタックの関連付けの削除

unstack でスタックとしての管理・関連付けを解除します。

gh stack unstack

ローカルの追跡情報だけを外す場合は以下のように実行します。

gh stack unstack --local

これは基本的にスタック関係の解除で、ブランチやPRそのものは削除されません。

view:スタックの表示

view で現在のスタックを表示します。引数未指定の場合は対話的な表示となります。

gh stack view

単純なテキストまたはJSON形式で表示する場合は以下のように実行します。

gh stack view --short
gh stack view --json

リモート操作

リモート側の操作コマンドは以下のようになります。

コマンド 役割
push スタック内のブランチだけをリモートへpushする
submit push、PR作成・更新、GitHub上のスタック作成までまとめて行う
sync fetch、rebase、push、PR・スタック状態の同期をまとめて行う
rebase trunkから上へ、スタック全体を順番にrebaseする
link ローカル追跡を使わず、既存ブランチやPRをGitHub上でスタックにする
merge スタックをGitHub上でまとめてマージする

push: スタック内のブランチをリモートへpush

push でスタック内のブランチをリモートへpushします。

gh stack push

PRの作成はしません。つまりまだリモート側にstackは作成されません。

submit: スタックの変更をGitHubへ公開

submit は普段スタックの変更をGitHubへ公開するときの中心的なコマンドとなります。

gh stack submit

引数を指定しない場合、以下のような対話画面でPRの文面を記入することになります。

submit は次をまとめて行うことができます。

  1. 全ブランチをpushする
  2. 必要なPRを作成する
  3. 既存PRのbaseを更新する
  4. GitHub上のstackを作成・更新する(ただしPRが2個以上でないとスタックは作成されない)

重要な注意点は最後の部分で、PRが1この場合はローカルではスタックが作成されていても、GitHub上ではスタックは作成されません。
複数のブランチをスタックに入れている場合のみ、GitHub上でスタックが作成されます。

対話画面を使わず自動生成する場合は以下を実行します。(PRの本文には何も記載されません)

gh stack submit --auto

--auto を指定した場合は、新規PRがデフォルトでDraftになります。
そのため、すぐレビュー可能にする場合は以下のように指定します。

gh stack submit --auto --open

sync: スタックの同期と構成の整理

sync はスタックをローカルとリモートで同期したり、スタック内のブランチ構成を整合させる処理を行います。

gh stack sync

例えば、以下のようなユースケースで使います。

  • trunk(スタックのベース)の最新変更を取り込み、スタック全体へ反映したい
  • スタック内の下位ブランチの変更を、依存する上位ブランチへ反映したい
  • リモートで更新されたスタックブランチを取り込みたい
  • 既存PRとGitHub上のスタックとの関連付けを整合させたい

基本的に sync は新しいPRを作成しないところは注意が必要です。
新規PRの作成も含めて公開する場合は submit を使います。また modify でスタック構成を変更した場合も submit を使います。

rebase: スタック全体を順番にrebase

rebase はtrunk(stackのベースとなるブランチ)の最新状態を取り込み、スタック内の後続のブランチまで順番にrebaseします。

gh stack rebase

通常の全体同期であれば rebase を単独で実行せず sync だけで足ります。

rebase を使うのは主に以下のような場合となります。

#----------------------------------
# 一部分だけrebaseしたいケース
#-----------------------------

# 現在ブランチからtopまでrebaseする
gh stack rebase --upstack

# trunkから現在ブランチまでrebaseする
gh stack rebase --downstack

# trunkを取り込まず、ブランチ間だけrebaseする
gh stack rebase --no-trunk

#-----------------------------------
# ローカル履歴だけ整えてpushしたいケース
#-----------------------------------
gh stack rebase

# その後push
gh stack push

link: リモート側のみで既存ブランチ/PRをスタックにする

link はGitHub上だけで既存ブランチ/PRをスタック化します。
これはgit-town、jj、Saplingなど、別ツールでローカルブランチを管理しており、GitHubのStacked PR機能だけを使いたい場合に向いています。

gh stack link feature/auth feature/api feature/ui

merge: スタックをまとめてマージ

merge はスタックをまとめてマージします。

gh stack merge

PRを指定すると、そのPRとそれより下のPRをまとめてマージします。
処理はatomicで、どれか1つでもマージできなければ全部マージされません。

マージ方式は --merge--squash--rebase から選ぶことができます。

ナビゲーション(スタック内のブランチ移動)

基本的にはブランチの移動は git checkout で行いますが、それとは別にスタック内を相対的に移動するコマンドが用意されています。

コマンド 移動先
bottom trunkに最も近いブランチ
top trunkから最も遠いブランチ
up top方向へ移動
down trunk方向へ移動
trunk main や develop などの基底ブランチ
switch スタック内のブランチを対話的に選択
# bottom: trunkに最も近いブランチ
gh stack bottom

# top: trunkから最も遠いブランチ
gh stack top

# up: top方向へ移動
gh stack up

# up: top方向へ移動(3段目)
gh stack up 3

# down: trunk方向へ移動
gh stack down

# down: trunk方向へ移動(2段目)
gh stack down 2

# trunk: main や develop などの基底ブランチ
gh stack trunk

# switch: スタック内のブランチを対話的に選択
gh stack switch

移動の際にマージ済みブランチは自動的にスキップされる点は注意が必要です。

まとめ

いかがでしたでしょうか。
GitHub上のUIはそこまで大きく変わっていませんが、CLIによる操作はかなり複雑なことができるようになっていることがわかりました。

かなりGitHubのコアに関わるアップデートで、開発の苦労についてもXのポストから伝わってきました。

https://x.com/sameenkarim/status/2083237928092721646

ぜひ活用されてください。

本記事がみなさまのご参考になれば幸いです。

この記事をシェアする

関連記事