TuBrief
Subscribed Channels
Videos
Community

巨大PRのせいでレビューが1週間も遅れる時に使いたい、スタックPRの実務移行法

TuBrief Editorial
August 7, 2026
0
Computing/Software

Written with AI assistance from the source video. The video is the authority.

日本語한국어EnglishEspañol中文हिन्दीDeutschFrançaisالعربيةPortuguêsРусскийBahasa Indonesia

Related Video

GitHubの数年ぶりの最大規模のリリース。スタックPR機能。5:17

GitHubの数年ぶりの最大規模のリリース。スタックPR機能。

Better Stack

More from the community

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

September 13, 2026

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

September 13, 2026

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

September 13, 2026

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

September 13, 2026

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

September 12, 2026

Apple Won the AI Race

September 12, 2026

Comments (0)

Log in to leave a comment

No posts yet

© 2026 . All rights reserved.

TuBrief
Subscribed Channels
Videos
Community
Log in

巨大PRのせいでレビューが1週間も遅れる時に使いたい、スタックPRの実務移行法

AIツールを導入し、コード生成のスピードは圧倒的に速くなりました。しかし、レビューのスピードがそれに追いついていません。2024年のDORA(DevOps Research and Assessment)レポートによると、AI導入率が高いチームはPRのサイズが平均154%大きくなり、レビューに要する時間が91%も増加しました。結果として、デプロイサイクルはむしろ遅くなりました。1,000行を超えるコードを一度にレビューしろと投げ出されれば、誰でも目が疲弊します。この混乱に終止符を打つには、コードを層状に積み上げるスタックPR(Stacked PRs)のチェーン構造に移行する必要があります。

1,000行の塊を3つのブランチに分割する

むやみにコードを切り捨てると、コンパイルが壊れたり依存関係が破綻したりします。確実な基準が必要です。単一PRは変更コード200行以下、修正ファイル10個未満に制限し、レビュアーが15分で終わらせられるようにしてください。巨大な機能1つは、最大3つの子ブランチチェーンに分割します。

  • Layer 1: DBスキーマ、Entity、DTO
  • Layer 2: ドメインロジック、サービス実装体
  • Layer 3: Controller、APIエンドポイント

この順序を徹底的に守ります。ブランチ名も feature/<機能名>/stack-<段階>-<説明> の形式で固定します。すでに絡まってしまった1,000行のブランチ(legacy-giant-branch)をチェーンに分解するプロセスはシンプルです。

まず main ブランチを最新化し、元のバックアップを取ります。

`bash
git checkout main
git pull origin main
git checkout legacy-giant-branch
git branch backup/legacy-giant-branch

`

次に main から Layer 1 ブランチを切り出し、スキーマ関連のコミットのみをチェリーピックして載せます。

`bash
git checkout -b feature/order-refactor/stack-1-schema main
git cherry-pick
git push origin feature/order-refactor/stack-1-schema

`

これで Layer 1 を親として、Layer 2 と Layer 3 を順次伸ばしていけばOKです。

`bash
git checkout -b feature/order-refactor/stack-2-service feature/order-refactor/stack-1-schema
git cherry-pick
git push origin feature/order-refactor/stack-2-service

git checkout -b feature/order-refactor/stack-3-controller feature/order-refactor/stack-2-service
git cherry-pick
git push origin feature/order-refactor/stack-3-controller

`

ツールの選択も悩みの種です。純粋な Git CLI はコストがかかりませんが手作業が多く、Graphite のような専用ツールは便利ですがコストとインフラへの依存性が生じます。

評価項目 Pure Git CLI GitHub CLI (gh stack) Graphite / External Tools
依存関係の追跡 手動ブランチ Base 設定 ローカル .git および GitHub metadata 別途リモートエンジンおよび Local DB
リベースの自動化 個別ブランチの手動作業 gh stack rebase コマンド実行 コミット変更時に下位チェーンを自動処理
学習曲線 高い(Git の原理熟知が必要) 低い(CLI 拡張のインストール) 中間(別途専用 UI への適応が必要)
運用安定性 100% 標準 Git 互換 パブリックプレビュー状態 非常に高い

親PRが修正された際のリベース競合を防ぐ

スタックPRを使っていると、親PRの修正リクエストが来る瞬間が最も苦痛です。コミットハッシュが変わることで、その下についている子ブランチがすべて壊れてしまうからです。そのまま git rebase を実行すると、コミットが重複して入ってしまいます。git rebase --onto 構文で切り取る範囲を指定する必要があります。

Layer 1 が修正された場合は Layer 2 に移動し、修正前の Layer 1 のコミット時点から現在の HEAD までを、新しい Layer 1 の終点の上に再配置します。

`bash
git checkout feature/order-refactor/stack-2-service
git rebase --onto feature/order-refactor/stack-1-schema feature/order-refactor/stack-2-service
git push --force-with-lease

`

Layer 3 も同様に新しい Layer 2 の上に移動させます。

`bash
git checkout feature/order-refactor/stack-3-controller
git rebase --onto feature/order-refactor/stack-2-service feature/order-refactor/stack-3-controller
git push --force-with-lease

`

この作業を手動で毎回行えば、人間は必ずミスをします。シェルスクリプトを作成し、順次リベースを自動化してください。

`bash
#!/usr/bin/env bash
set -e

STACK_BRANCHES=(
"feature/order-refactor/stack-1-schema"
"feature/order-refactor/stack-2-service"
"feature/order-refactor/stack-3-controller"
)
TARGET_BASE="main"

git fetch origin
CURRENT_PARENT="$TARGET_BASE"

for BRANCH in "STACKBRANCHES[@]";dogitcheckout"{STACK_BRANCHES[@]}"; do git checkout "STACKB​RANCHES[@]";dogitcheckout"BRANCH"
OLD_BASE=(gitmerge−base"(git merge-base "(gitmerge−base"CURRENT_PARENT" "BRANCH"2>/dev/null∣∣echo"")if[−n"BRANCH" 2>/dev/null || echo "") if [ -n "BRANCH"2>/dev/null∣∣echo"")if[−n"OLD_BASE" ]; then
git rebase --onto "CURRENTPARENT""CURRENT_PARENT" "CURRENTP​ARENT""OLD_BASE" "BRANCH"∣∣exit1figitpush−−force−with−leaseorigin"BRANCH" || exit 1 fi git push --force-with-lease origin "BRANCH"∣∣exit1figitpush−−force−with−leaseorigin"BRANCH"
CURRENT_PARENT="$BRANCH"
done

`

Git の設定に競合解決履歴の記録機能を有効にしておくことも忘れないでください。繰り返される競合を自動でスキップしてくれます。

`bash
git config --global rerere.enabled true
git config --global rerere.autoupdate true
git config --global rebase.autoStash true
git config --global rebase.updateRefs true

`

CI ランナーのコスト浪費とマージ順序の狂いを遮断する

PRを3つに分割すると、CI ランナーも3倍回るという問題が生じます。すべての PR で重い E2E テストを実行する必要はありません。下位レイヤーでは堅実な単体テストのみを実行し、全体の統合検証は最上位 PR でのみ実行するように GitHub Actions 環境を構築してください。

.github/workflows/ci.yml にスタック位置の条件文を追加します。

`yaml
name: Stack-Aware CI Pipeline

on:
pull_request:
branches: [ main ]

jobs:
fast-lint-and-unit-test:
name: Fast Validation (All Layers)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Linter & Unit Tests
run: |
npm ci
npm run test:unit

heavy-integration-test:
name: Full E2E Test (Top Layer Only)
runs-on: ubuntu-latest
if: |
github.event.pull_request.stack == null ||
github.event.pull_request.stack.position == github.event.pull_request.stack.size
steps:
- uses: actions/checkout@v4
- name: Run Heavy Integration & E2E Tests
run: |
npm ci
npm run test:e2e

`

組織レベルでのブランチ保護ルールの設定も必須です。

  1. GitHub Merge Queue 機能を有効にし、承認されたスタックPRが順番にマージされるように強制します。
  2. Repository Rulesets で 'Require Linear History' を有効にし、不要なマージコミットを防ぎます。
  3. 'Require Status Checks to Pass Before Merging' により、下位PRがマージされていない状態で上位PRが先に main に混ざる事故を防ぎます。

チームのレビュー文化と Squash Merge 後の UI 崩れへの対処

スタックPRを正常に機能させるには、レビュアーが全体像を把握できなければなりません。.github/PULL_REQUEST_TEMPLATE.md にスタックマップを明記してください。

`markdown
Stack Overview
この PR は Order Refactoring Stack チェーンの一部です。

  1. #101 - feature/order-refactor/stack-1-schema (DB Migration)
  2. [Current PR] #102 - feature/order-refactor/stack-2-service (Business Logic)
  3. #103 - feature/order-refactor/stack-3-controller (API Controller)

Current Layer Scope

  • OrderService 内の決済状態変更ロジックの実装
  • ドメインイベント発行処理および Repository 連携テストの追加

Dependency Status

  • Base PR: #101 (Must be merged first)

`

下位PR #101 が Squash Merge で main に取り込まれた後、子PR #102 の GitHub UI Diff が急激に膨れ上がります。すでにマージされた #101 のコードまでがすべて子PRの変更事項として捉えられてしまう現象です。Git Commit Graph 上で Squash コミットの SHA と親コミットの SHA が変わってしまったために発生します。慌てずに以下の手順で子ブランチのコミットのみを main の上に引き上げればOKです。

`bash
git log --graph --oneline
git checkout feature/order-refactor/stack-2-service
git fetch origin
git rebase --onto origin/main feature/order-refactor/stack-2-service
git push --force-with-lease origin feature/order-refactor/stack-2-service

`

巨大な1,000行のPRを分割する作業は、単に Git の技術を扱う問題ではありません。チームのコード検査方式とデプロイチェーン全体を綺麗に整えるエンジニアリング作業に近いです。散らかったレガシーブランチに直面したら、まずはバックアップを作成し、3段階のレイヤーに切り分けてみてください。レビュアーの疲弊が軽減されるのはもちろん、自分自身もコードをより明確にコントロールできるようになります。