GitHub Stacked PRs
(github.github.com/gh-stack)- 大規模なコード変更を小さくレビューしやすいPR単位に分割し、順番に管理できるようにするGitHubの新機能
- 各PRは独立してレビューされ、スタック全体はワンクリックでマージ可能
- GitHub UIと
gh stackCLIを通じてスタックの作成、移動、リベース、マージをサポートし、スタックマップで階層構造を可視化 - AIコーディングエージェント統合により、大規模なdiffを自動でスタック単位に分割したり、スタックベースの開発を行ったりできる
- 大規模PRの複雑さと競合リスクを減らし、レビュー効率とチーム開発速度を高めることが目的
主な機能
-
スタック型PR管理
- 複数のPRを順序付きのスタック(stack) 形式で構成し、各PRは直下のPRのブランチを基盤とする
- 最終的にメインブランチへ到達するチェーン構造を形成
- GitHubはスタック全体を認識してUIにスタックマップ(stack map) を表示し、レビュアーが各階層を簡単に移動可能
- ブランチ保護ルールは最終的な対象ブランチに適用され、CIテストはスタック内のすべてのPRに対して実行される
-
簡素化されたスタック管理
- GitHub UIでスタック内のPR間を移動し、各階層の状態を確認し、スタック全体に対する連鎖リベース(cascading rebase) を実行可能
- ワンクリックでスタック全体をマージすることも、一部だけをマージすることも可能
- マージ後に残ったPRは自動でリベースされ、最下層の未マージPRがベースブランチを対象に調整される
-
強力なCLIサポート
gh stackCLIにより、スタック作成、リベース、ブランチのプッシュ、PR作成、階層間の移動をターミナルで実行可能- CLIコマンド例
gh extension install github/gh-stack: 拡張機能をインストールgh stack alias: 短縮コマンドを設定gs init <branch>: 最初のブランチを作成gs add <branch>: 新しい階層を追加gs push: すべてのブランチをプッシュgs submit: スタック全体のPRを作成
-
AI Agent統合
npx skills add github/gh-stackコマンドでAIコーディングエージェントがスタック作業を実行できるよう学習させられる- 大規模なdiffを自動でスタック単位に分割したり、最初からスタックベースの開発を進めたりできる
スタック型PRが必要な理由
- 大規模PRはレビュー難易度の上昇、マージ遅延、競合リスクを招く
- レビュアーが文脈を見失い、フィードバックの質が低下し、チーム全体の速度が落ちる
- Stacked PRsはこれを解決するため、小さく焦点の定まったPRチェーンに分割する
- 各PRは独立してレビュー可能で、変更全体は順番に積み上がる
はじめ方
- すぐに使うにはQuick Startガイド またはOverviewドキュメント を参照
1件のコメント
Hacker Newsの意見
私に必要なのは「stacked PR」ではなく、単一コミット管理用UIだ
Gitはすでにコミットという概念を持っているのに、なぜその上にさらに「stacked PR」という抽象化を載せるのかわからない
まだマージされていない作業の上で新しい作業を進めやすくし、レビュアーが大きな変更を 小さな単位で独立してレビュー できるようにする
大規模なmonorepoや企業環境では特に有用だった
squash、rebase、force pushを繰り返すのは自分の足を撃つようなものだ
git merge --no-ff、git log --first-parent、git bisect --first-parentでも十分同じ効果を得られるinteractive smartlogドキュメント で公開されていて、VSCode拡張もある
意外なほど広く使われなかったのが残念だ
コミットはそのPRを完成させるための進化の過程として使う
PhabricatorとMercurialを使ってからGitHubに戻ると、石器時代 に戻った気分になる
stacked diffの流れを再実装してくれるjujutsuや今回の機能は歓迎だ
monorepoだけでなく長期の機能開発でも、レビューを小さく速くできるようにしてくれる
Mercurialはいつも「gitより速い」と言っていたが、実際には遅かったり壊れたりしていた
Gitは 醜いが速くて信頼できる
大きな変更(例: vendor依存関係の更新)をレビューするとき、GitHubのファイルレビュー体験は微妙だ
ついに来た!
GitHubの「PR=ブランチ」モデルは理解できなかった
Phabricator/Gerrit式のstacked commit の方が自分の考え方に合っている
これでCLIをインストールしないといけないな
ブランチは単にコミットに旗を立てるだけで、複数の地点を残すことに意味があるのは、前の部分を独立してマージできるときだけだ
現在 Squash & MergeのUX問題 を解決したのか気になる
私は手動で main <- PR A <- PR B <- PR C のように積んでいるが、
PR Aが先にマージされるとPR Bは衝突地獄になる
GitHub UIが自動でターゲットブランチをmainに変えて 妙な衝突 が発生する
とにかく「ちゃんと動く」ツールが必要だ
gh stack syncがrebase --ontoで解決してくれることを期待するgit rebase --ontoにより処理している例: PR1(main<-A,B)、PR2(main<-A,B,C,D)、PR3(main<-A,B,C,D,E,F)
PR1、2がsquashマージされると、mainは S1(A+B)、S2(C+D) になる
その後
git rebase --onto S2 D branch3で衝突なく整理できるgit rebase --update-refs --onto origin/main A Cで解決できるGH CLIがこの過程を自動化してくれる
だが解決策は結局、手動rebaseでコミットを整理することしかない
一人で開発するときはstacked PRはほとんど必要ないが、小さな単位に分ける習慣 は依然として重要だ
AIツール(例: Claude Code)が一度に大きなdiffを作るので、
エージェントが自分で作業を論理的な単位に分ける機能が出てきたら面白いと思う
git-spice も試してみる価値がある
GitLabなどと互換性があり、私は既存のgitコマンドの代わりに全部git-spiceを使っている
GitHubがついにUIに stack機能 を入れたのは素晴らしい
GitLabの
glab stackに似ているただしマージの流れは少しぎこちなさそうだ — スタックの下側をマージすると残りがrebaseされて CIが再実行される
3つのパッチのうち下2つだけをマージしたい場合、それぞれのテスト待ちが必要になる
その後、上側のスタックがrebaseされてCIが再実行される可能性がある
ドキュメントにもこの点を明確に追記する予定だ
私は stacked PRの必要性 がよくわからない
gitではもともとパッチセットを個別にレビューして適用できる
PRモデルの方がむしろこれを ひとつの塊にまとめてしまう
stacked PRはその問題を回避するための別の抽象化に見える
内部コミットは開発履歴にすぎず、マージ時には squash してひとつにまとめる
こうすれば開発中は自由にコミットを積めて、マージ時にはきれいな変更だけが残る
GitHubの実装は少し 後付けの機能 のように感じる
つまり、レビュー可能な単位で 作業を段階的に積み上げる構造 だ
Graphite というスタートアップがすでにstacked PRに注力している
私はGraphiteを使ってきたので、GitHubが似たものを実装したのはうれしい
私はstacked PRは好きだが、今回のGitHub実装は 変なやり方 に感じる
単に各ブランチが親を指すようにすれば十分だ
CLIより UIサポート の方が必要だ
CLIがこの過程を自動化してくれるとよさそうだ
ブランチチェーンを置く理由は、diffが そのブランチの変更だけを表示するため だ
ただ、UIと可視化が不足していただけだ