大きなプルリクエストはレビューが難しく、ボトルネックを生み出します。特に、短時間で大量のコードを生成する場合はなおさらです。 pull request サイズが大きくなると、レビューの品質も低下します。 レビュー担当者は、結果をざっと確認し、問題を見落とし、または先延ばしにして、古くなりマージ競合が発生するまで pull request を放置してしまうことがあります。
スタック プル リクエストでは、大きなコード変更をレビュー可能な状態に保ちます。
スタックは、同じリポジトリ内の一連のプル要求です。各プル要求は、その下のプル要求のブランチを対象とし、1 つのブランチ (通常はメイン ブランチ) に配置される順序付きチェーンを形成します。 1 つの大きなプル要求の代わりに、一連の小さなプル要求を取得します。 各プル要求には独自のフォーカスされた差分があるため、チームメイトは各レイヤーを個別に確認して承認できます。
このチュートリアルでは、スタックプルリクエストを使用して、個別にレビュー可能なレイヤーごとに機能を実装する方法について説明します。 この例では、アプリにユーザー認証を追加する方法を検討します。
gh stackでは、GitHub CLI拡張機能を使用します。
Prerequisites
このチュートリアルに従うには、 GitHub CLI と gh stack 拡張機能をインストールする必要があります。 以下のものが必要です。
- GitHub CLI (
gh) 2.90.0 以降、および Git 2.20 以降。gh auth loginを使用してGitHub CLIを認証します。
- プッシュできる GitHub リポジトリ。
GitHub CLIで、gh stack拡張機能をインストールします。
gh extension install github/gh-stack
1. コードを生成する前にスタックを設計する
良いスタックは家を建てるようなものです:強い基盤から始め、壁の骨組みを作り、配線を取り付け、その後、壁板を仕上げます。 各レイヤーは、直下のレイヤーに依存して構築されます。 最終的に、レビュー担当者は、下から上にプルリクエストを読み取り、機能の開発過程を追える必要があります。
- 機能をレイヤーに分割します。 各レイヤーは、単独で確認できる単一の一貫性のある変更である必要があります。
- 各レイヤーは、プルリクエストが簡単に読み取れるほど小さくします。 レイヤーのレビューに長い説明が必要だと感じる場合は、おそらく大きすぎます。
- 境界を自分で決めてください。 スタックの形状を制御できる。
- 依存関係別にレイヤーを並べ替える。 基本的な変更は下部に配置します。 それらに依存するものは、上位になります。 認証では、次のようになります。
- レイヤー1: データモデルと移行
- レイヤー 2: CRUD エンドポイント
- レイヤー 3: JWT ミドルウェアとガード
- レイヤー 4: 統合テストと単体テスト
2. まず下部レイヤーを構築します
土台を使用してスタックを開始します。 上記のすべては、このレイヤーを正しく設定することに依存します。
- スタックを作成し、プランに基づいて最初のレイヤーを構築します。
gh stack init BRANCH-NAME-1で作成し、プレフィックスを使用してブランチ名を整理することを検討してください。 - 次に進む前に、自分で変更を確認してください。 下位レイヤーの間違いは、その上のすべてのブランチに波及するため、次に進む前にレビューを行ってください。
3. 新しい各コード レイヤーをその上に順に重ねる
基盤を整えた状態で、フィーチャの残りの部分を 1 レイヤーずつ構築します。
- 次のレイヤーを追加し、以下のレイヤーのコンテキストで実装します。
gh stack add BRANCH-NAME-NEXTを使用してスタックの先頭にブランチを追加し、そこで作業をコミットします。 - レイヤーが大きくなりすぎる場合は、当初の計画から逸脱していないか、または 1 つではなく実際には 2 つのレイヤーが必要かどうかを検討します。
- レイヤーごとに新しいブランチを作成し、すべてのブランチがクリーンで自己完結型の差分を維持するようにします。
- pull request を作成する準備ができたら、
gh stack submitを使用してスタックを送信してください。 - 各プルリクエストはそれ自体で完結させます。 通常は、焦点を絞ったタイトルと、レイヤーの簡潔でわかりやすい説明で十分です。
4. レビューを依頼する前に pull request を自分で確認する
各レイヤーは小さく、自己レビューも簡単になります。 チームメイトを巻き込む前に、すべてのブランチをひととおり確認します。 レビュー担当者は、既に信頼済みの変更を受け取る必要があります。
- レビューを依頼する前に、各ブランチでテスト、リンター、コード スキャンを実行して、各レイヤーを標準に照らしてチェックします。
5. スタックのレビューを一番下から要求する
レイヤーを構築すると、校閲者はコードの大きな壁ではなく、小さな差分を取得します。
- 依存関係が厳密に統合されている場合は、スタックの下部からレビューを依頼して、後続のレビューの前に変更をスタックの上位へ順次反映できるようにします。
- 異なるレイヤーについて別々の担当者からのレビューが必要な場合は、レビュー担当者が並行して作業できます。 1 人のユーザーがデータ モデルを確認でき、別のユーザーがエンドポイントを確認し、どちらも機能全体のレビューに苦労せずに済みます。
6. フィードバックを基に改善する
フィードバックは、機能全体ではなく、レイヤーに個別に反映されます。 スタックを使用すると、適切なレイヤーを所定の位置に固定し、変更を上位レイヤーに反映できます。
- レビュー担当者が指摘したレイヤーを修正します。 右側のブランチに移動し、変更を加えて、そこでコミットします。
- 各修正は、それが属するレイヤーに入れておきます。 間違ったブランチで行われた変更により、混乱を招き、スタック上位でエラーを引き起こす可能性があります。
gh stack down、gh stack up、またはgh stack checkout BRANCH-NAMEを使用してブランチ間を移動します。 次に、変更をコミットし、gh stack rebase --upstackを実行して上記のブランチをリベースし、gh stack pushを実行して変更をスタックの上位ブランチへ反映させます。
7. 下のレイヤーから結合する
スタックは、メイン ブランチを指すレイヤーから順にマージされます。 レイヤーを一度に、または1つずつマージし、GitHubが自動的に次のレイヤーがmainを参照するように再ターゲットします。
- スタックを一番下から順に 1 つずつマージするか、スタック内の任意の場所からマージすると、マージするプル要求の下にあるすべてのブランチが一番下から順にマージされます。
- 各レイヤーの差分は親に対してまったく同じままで、ベースだけが変わるため、進行中の作業やレビューに影響を与えることなく、レイヤーを1つずつ簡単にマージできます。
- マージ キューを使用して、各レイヤーが承認され、そのチェックが成功した後に順番にマージされるようにします。 スタック全体の完了を一度に待つ必要はありません。
最上位レイヤーがマージされると、フィーチャ全体が反映されます。 すべての部分は、1 つの大きなプルリクエストではなく、小さな意図的な変更としてより効果的にレビューされました。