はじめに

プルリクエスト(Pull Request、略してPR)は、GitHubのコラボレーション機能の中核です。 この章では、プルリクエストの概念から実践的な使い方、そして様々なマージ戦略まで、 チーム開発に必要な知識を包括的に学びます。

学習のポイント

プルリクエストは単なる技術的な機能ではなく、コミュニケーションツールでもあります。コードレビューの文化と合わせて理解することが重要です。

3.1 プルリクエストの概念と重要性

プルリクエストとは

プルリクエストは、あるブランチの変更を別のブランチにマージするための提案です。 以下のような特徴があります:

変更の可視化

何が変更されたかを明確に表示し、差分を確認できる

ディスカッション

コードに関する議論やフィードバックを行える

品質保証

レビューやテストを通じてコード品質を維持

履歴管理

なぜその変更が必要だったかの記録を残せる

プルリクエストのワークフロー

  1. 1
    フィーチャーブランチの作成

    新機能や修正用のブランチを作成

  2. 2
    変更の実装とコミット

    機能を実装し、適切にコミット

  3. 3
    プルリクエストの作成

    変更内容の説明とレビュー依頼

  4. 4
    コードレビュー

    チームメンバーによるレビューとフィードバック

  5. 5
    マージ

    承認後、メインブランチへマージ

プルリクエストの利点

  • コード品質の向上 - 複数の目によるレビューでバグや問題を早期発見
  • 知識共有 - チーム全体でコードベースの理解を深める
  • 履歴の透明性 - なぜその変更が行われたかの文脈を保存
  • 継続的インテグレーション - 自動テストやビルドとの統合

3.2 プルリクエストの作成

準備作業

プルリクエストを作成する前に、以下の準備を行います:

Bash
# 1. フィーチャーブランチで作業
git checkout -b feature/user-authentication

# 2. 変更を実装してコミット
git add .
git commit -m "feat: ユーザー認証機能を実装"

# 3. リモートにプッシュ
git push -u origin feature/user-authentication

# 4. メインブランチの最新変更を取り込む(推奨)
git fetch origin
git merge origin/main
# またはリベース
git rebase origin/main

GitHub上でのプルリクエスト作成

ステップ1: プルリクエストページへ移動

ブランチをプッシュ後、GitHubリポジトリページに表示される「Compare & pull request」ボタンをクリック

ステップ2: ベースブランチとの比較

マージ先(base)とマージ元(compare)のブランチが正しいことを確認

ステップ3: タイトルと説明の記入

変更内容を明確に伝えるタイトルと詳細な説明を記入

効果的なプルリクエストの書き方

## 概要

このPRで実装した機能や修正内容の簡潔な説明

## 変更内容

- ユーザー認証機能の実装
- JWTトークンによるセッション管理
- ログイン/ログアウトAPI

## 関連Issue

Closes #123

## テスト方法

1. `npm install`で依存関係をインストール
2. `npm test`でテストを実行
3. ログイン機能の動作確認手順...

## スクリーンショット(該当する場合)

![ログイン画面](login-screenshot.png)

## チェックリスト

- [ ] コードは自己レビュー済み
- [ ] テストを追加/更新した
- [ ] ドキュメントを更新した
- [ ] 破壊的変更がない

プルリクエストのテンプレート活用

リポジトリに`.github/pull_request_template.md`を作成することで、テンプレートを自動適用できます:

Markdown
## 概要


## 変更内容

- 
- 

## 関連Issue

Closes #

## テスト

- [ ] ユニットテスト追加/更新
- [ ] 統合テスト確認
- [ ] 手動テスト完了

## レビュー観点


## その他

実践演習 3.1

効果的なプルリクエストの作成:

  1. 新しいブランチで簡単な機能を実装
  2. 適切なコミットメッセージで複数回コミット
  3. GitHubでプルリクエストを作成
  4. テンプレートに従って詳細な説明を記入
  5. ラベルやアサインを設定

3.3 コードレビューのベストプラクティス

レビュアーの心得

建設的なフィードバック

  • 問題点だけでなく、改善案も提示する
  • 良い点も積極的に褒める
  • 「なぜ」その変更が必要かを説明する

レビューの観点

  • 機能性 - 要件を満たしているか
  • 可読性 - コードが理解しやすいか
  • 保守性 - 将来の変更が容易か
  • パフォーマンス - 効率的に動作するか
  • セキュリティ - 脆弱性がないか

コミュニケーション

  • 敬意を持って接する
  • 質問形式で疑問を投げかける
  • コードを批判するのではなく、改善に焦点を当てる

GitHubのレビュー機能

GitHubは強力なコードレビュー機能を提供しています:

インラインコメント

JavaScript
function calculateTotal(items) {
    let total = 0;
    // コメント: forEachの方が読みやすいかもしれません
    for (let i = 0; i < items.length; i++) {
        total += items[i].price;
    }
    return total;
}

サジェスチョン機能

具体的な修正案を提示できます:

```suggestion items.forEach(item => { total += item.price; }); ```

レビューステータス

  • ✓ Approve - 変更を承認
  • 💬 Comment - コメントのみ
  • ✗ Request changes - 修正を要求

効果的なレビューコメントの例

❌ 悪い例

"このコードは読みにくい"

"なんでこんな書き方してるの?"

"これは間違ってる"

✅ 良い例

"この部分を関数に切り出すと可読性が向上しそうです"

"この実装方法の意図を教えていただけますか?〇〇の観点から△△の方が良いかもしれません"

"ここでnullチェックが必要かもしれません。エッジケースとして..."

レビュー対応のベストプラクティス

作成者側の心得
  • フィードバックに対して防御的にならない
  • 不明な点は積極的に質問する
  • 修正内容をコミットメッセージで明確にする
  • レビュアーへの感謝を忘れない

実践演習 3.2

コードレビューの練習:

  1. パートナーとプルリクエストを交換
  2. 少なくとも3つの建設的なコメントを追加
  3. 1つ以上のサジェスチョンを提供
  4. 適切なレビューステータスを設定
  5. フィードバックに基づいて修正を実施

3.4 マージ戦略の詳細

3つの主要なマージ方法

GitHubでは3つのマージ方法を選択できます。それぞれの特徴と使い分けを理解しましょう:

1. Merge Commit(マージコミット)

Git Graph
     feature
    ●───●───●
   ╱         ╲
●───●───●───●───●  main
              ↑
         マージコミット

特徴:

  • ブランチの履歴を完全に保持
  • マージコミットが作成される
  • プルリクエストの文脈が明確

使用場面:

  • 大きな機能開発の統合
  • 複数人での共同作業の記録を残したい場合
  • 履歴の完全性を重視する場合
Bash
git checkout main
git merge --no-ff feature-branch

2. Squash and Merge(スカッシュマージ)

Git Graph
     feature
    ●───●───●
   ╱
●───●───●───●───●  main
              ↑
         全てを1つのコミットに

特徴:

  • 複数のコミットを1つに統合
  • きれいな履歴を維持
  • 作業過程の詳細は隠蔽

使用場面:

  • 小さな機能やバグ修正
  • 試行錯誤の過程を残したくない場合
  • メインブランチの履歴をシンプルに保ちたい場合
Bash
git checkout main
git merge --squash feature-branch
git commit -m "feat: 新機能の追加"

3. Rebase and Merge(リベースマージ)

Git Graph
Before:      feature
          ●───●───●
         ╱
●───●───●           main

After:
●───●───●───●───●───●  main
         ↑ ↑ ↑
    リベースされたコミット

特徴:

  • 直線的な履歴を作成
  • マージコミットなし
  • 各コミットは保持される

使用場面:

  • クリーンな履歴を重視する場合
  • 個々のコミットが意味を持つ場合
  • bisectなどでの調査を考慮する場合
Bash
git checkout feature-branch
git rebase main
git checkout main
git merge --ff-only feature-branch

マージ戦略の選択ガイド

シナリオ 推奨戦略 理由
大規模な機能開発 Merge Commit 開発過程の記録が重要
小さなバグ修正 Squash and Merge 履歴をシンプルに保つ
依存関係のある複数PR Rebase and Merge 順序を保持したい
実験的な変更 Squash and Merge 試行錯誤を隠蔽
注意事項

チーム内でマージ戦略を統一することが重要です。プロジェクトの性質に応じて、デフォルトの戦略を決めておきましょう。

3.5 コンフリクト解決の実践

コンフリクトが発生する理由

コンフリクトは、同じファイルの同じ部分を複数の人が異なる方法で変更した場合に発生します。 これは正常な開発プロセスの一部であり、適切に解決することが重要です。

コンフリクトの解決手順

1. コンフリクトの確認

Bash
# プルやマージ時にコンフリクトが発生
git pull origin main
# Auto-merging index.js
# CONFLICT (content): Merge conflict in index.js
# Automatic merge failed; fix conflicts and then commit the result.

# コンフリクトしているファイルを確認
git status
# Unmerged paths:
#   both modified:   index.js

2. コンフリクトマーカーの理解

JavaScript
function calculatePrice(quantity, price) {
<<<<<<< HEAD
    // 自分の変更
    const tax = 0.08;
    return quantity * price * (1 + tax);
=======
    // 他者の変更
    const tax = 0.10;
    const discount = quantity > 10 ? 0.1 : 0;
    return quantity * price * (1 + tax) * (1 - discount);
>>>>>>> feature-branch
}

3. 手動での解決

JavaScript
function calculatePrice(quantity, price) {
    // 両方の変更を統合
    const tax = 0.10; // 新しい税率を採用
    const discount = quantity > 10 ? 0.1 : 0; // 割引機能も採用
    return quantity * price * (1 + tax) * (1 - discount);
}

4. 解決の完了

Bash
# 解決したファイルをステージング
git add index.js

# コミットして解決を完了
git commit -m "fix: マージコンフリクトを解決"

# またはマージを続行
git merge --continue

GitHubでのコンフリクト解決

GitHubのWebインターフェースでも簡単なコンフリクトは解決できます:

  1. プルリクエストページで「Resolve conflicts」ボタンをクリック
  2. エディタでコンフリクトを解決
  3. 「Mark as resolved」をクリック
  4. 「Commit merge」で変更を保存

コンフリクトを避けるベストプラクティス

頻繁な同期

定期的にメインブランチの変更を取り込む

小さなPR

変更を小さく保ち、早めにマージする

コミュニケーション

チームで作業範囲を共有する

ファイル分割

大きなファイルは適切に分割する

実践演習 3.3

コンフリクト解決の練習:

  1. 2つのブランチで同じファイルの同じ部分を変更
  2. プルリクエストを作成してコンフリクトを発生させる
  3. コマンドラインでコンフリクトを解決
  4. 別のコンフリクトをGitHub上で解決
  5. 解決後、正しく動作することを確認

3.6 高度なプルリクエスト機能

ドラフトプルリクエスト

作業中の変更を早期に共有し、フィードバックを得るための機能です:

  • WIP(Work In Progress)の状態を明示
  • 自動的にマージがブロックされる
  • 早期のフィードバックが可能
  • 「Ready for review」で通常のPRに変換

プルリクエストの自動化

ブランチ保護ルール

Settings
Settings → Branches → Add rule
- Require pull request reviews before merging
- Require status checks to pass before merging
- Require branches to be up to date before merging
- Include administrators
- Restrict who can push to matching branches

自動マージ設定

条件を満たしたら自動的にマージする機能:

  • 全てのチェックがパス
  • 必要な承認を取得
  • コンフリクトなし

GitHub Actionsとの連携

YAML
name: PR Checks
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run tests
        run: |
          npm install
          npm test
      
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run linter
        run: |
          npm install
          npm run lint

プルリクエストのリンク機能

Issue との連携

PRの説明で以下のキーワードを使用:

  • Closes #123 - PRマージ時にIssueを自動クローズ
  • Fixes #456 - 同上
  • Resolves #789 - 同上
  • Related to #101 - 関連付けのみ

他のPRとの関連付け

依存関係があるPRを明示:

Depends on #234
Blocked by #567
Part of #890

プロのヒント

複雑な機能は複数の小さなPRに分割しましょう。 各PRは独立してレビュー・マージ可能にし、 全体の進捗を親Issueで管理すると効果的です。

3.7 まとめと次のステップ

この章で学んだこと

  • プルリクエストの概念と重要性
  • 効果的なPRの作成方法
  • コードレビューのベストプラクティス
  • 3つのマージ戦略とその使い分け
  • コンフリクト解決の実践
  • 高度なPR機能の活用

チェックリスト

プルリクエスト作成時

  • 変更内容は明確か
  • テストは追加/更新したか
  • ドキュメントは更新したか
  • コミットメッセージは適切か
  • 関連Issueはリンクしたか

レビュー時

  • 要件を満たしているか
  • コードは読みやすいか
  • エッジケースは考慮されているか
  • パフォーマンスの問題はないか
  • セキュリティの問題はないか

理解度チェック

確認問題

  1. プルリクエストを使う主な利点を3つ挙げてください
  2. Squash and MergeとRebase and Mergeの違いを説明してください
  3. 効果的なコードレビューコメントの特徴は何ですか?
  4. コンフリクトを防ぐための方法を3つ挙げてください
  5. ドラフトプルリクエストはどのような場面で使用しますか?

次章への準備

第4章では、GitHubのIssue機能とプロジェクト管理について学びます。 プルリクエストと組み合わせることで、より効果的なプロジェクト管理が可能になります。