はい、承知いたしました。GitHubプルリクエストの基本的なやり方について、約5000語の詳細な説明を含む記事を作成します。
GitHubプルリクエスト入門:基本的なやり方と共同開発のすすめ
ソフトウェア開発の世界において、チームでの開発は不可欠です。複数の開発者が同時にコードを書き、変更を共有し、統合していく過程で、いかに効率的かつ安全に進めるかがプロジェクト成功の鍵となります。そこで中心的な役割を果たすのが「バージョン管理システム」であり、中でも「Git」は現在最も広く利用されているシステムの一つです。そして、Gitを使った共同開発をさらにスムーズに進めるために、GitHubのようなプラットフォームが提供する「プルリクエスト(Pull Request)」という機能が絶大な力を発揮します。
この記事では、GitHubを使った開発におけるプルリクエストの基本的な概念から、実際にプルリクエストを作成し、レビューを受け、マージするまでの一連の流れを、初心者の方にも分かりやすく詳細に解説します。プルリクエストがなぜ重要なのか、どのように機能するのかを理解し、日々の開発業務に活かせるようになることを目指します。
1. はじめに:なぜバージョン管理とGitHub、そしてプルリクエストなのか
ソフトウェア開発では、コードは日々変化します。新しい機能が追加され、バグが修正され、既存のコードが改善されます。これらの変更を記録し、管理し、必要に応じて過去の状態に戻したり、複数の開発者が同時に行った変更を統合したりするための仕組みが「バージョン管理システム(VCS)」です。
VCSの最も基本的な役割は、コードの履歴を保存することです。これにより、「いつ」「誰が」「何を」変更したのかが明確になり、問題が発生した際に原因を特定したり、以前の安定したバージョンに戻したりすることが容易になります。
VCSには、変更履歴を中央サーバーで一元管理する「集中型VCS」(例: Subversion)と、各開発者が自身のローカル環境に完全な変更履歴を持つ「分散型VCS」(例: Git)があります。Gitは分散型VCSの代表であり、その柔軟性と堅牢性から、個人開発から大規模なチーム開発まで、世界中で幅広く利用されています。
Gitの登場により、開発者はネットワークに接続されていないオフライン環境でもコミットやブランチの作成といった作業を行えるようになりました。これにより、開発のスピードと自由度が向上しました。
しかし、チームでGitを使う場合、開発者同士が自身の変更をどのように共有し、メインのコードラインに統合していくかという課題が生じます。この課題に対する有力な解決策を提供するのが、GitHubのようなGitホスティングサービスです。
GitHubは、Gitリポジトリをクラウド上でホスティングするだけでなく、チームでの共同開発を支援するための様々な機能を提供しています。その中でも最も重要な機能の一つが「プルリクエスト」です。
プルリクエストは、簡単に言えば、「私のコード変更をメインのブランチ(例えばmain
やdevelop
)に取り込んでください」という提案です。この提案は単なるコードの差分だけでなく、その変更に関する議論、コードレビュー、自動テストの結果確認など、共同開発に必要な多くの要素を含んでいます。
プルリクエストを経由することで、以下のようなメリットが得られます。
- コードレビューの促進: 他の開発者がコード変更を確認し、問題点や改善点を指摘できます。これにより、コードの品質向上やバグの早期発見につながります。
- 変更内容の可視化: プルリクエストページで、変更されたファイルやコードの差分、関連するコミット、議論の履歴などを一目で確認できます。
- 議論と意思決定: 変更内容について開発者間で議論を行い、合意形成を図ることができます。
- 自動化との連携: CI(継続的インテグレーション)ツールと連携し、プルリクエストが作成されるたびに自動でコードのビルドやテストを実行し、変更が既存のコードを壊していないかを確認できます。
- 履歴の記録: 誰がどのような提案をし、どのような議論を経て、最終的にコードがどのように変更されたかというプロセス全体がGitHub上に記録されます。
この記事を通して、あなたはプルリクエストの概念を深く理解し、GitとGitHubを使ったチーム開発に自信を持って参加できるようになるでしょう。さあ、GitHubプルリクエストの世界へ一緒に踏み出しましょう。
2. バージョン管理システムとGitの基本
プルリクエストを理解するためには、まずGitとバージョン管理の基本的な考え方を把握しておく必要があります。
2.1. バージョン管理システム(VCS)の必要性
個人の開発であれ、チームでの開発であれ、コードは常に変化します。機能追加、バグ修正、リファクタリングなど、様々な理由でコードは書き換えられます。バージョン管理システムがないと、以下のような問題が発生します。
- 変更履歴の喪失: 過去のバージョンに戻したい場合に、変更内容が記録されていないため不可能になります。
- ファイル名の煩雑化: 変更を記録するために、「index_v1.html」「index_final.html」「index_final_really.html」のようにファイルを複製し、意味不明な名前を付けて管理することになりがちです。
- 共同作業の困難さ: 複数の開発者が同じファイルを同時に変更すると、どちらかの変更が失われる可能性があります。変更を統合(マージ)する作業も非常に手間がかかります。
- 問題発生時の原因特定難: いつ、誰が行った変更によって問題が発生したのかを追跡することが困難になります。
バージョン管理システムは、これらの問題を解決するために生まれました。VCSは、ファイルやディレクトリの変更履歴を効率的に記録・管理し、過去の任意の時点の状態を復元したり、複数の開発者が行った変更を安全に統合したりする機能を提供します。
2.2. 集中型VCS vs 分散型VCS
バージョン管理システムには、主に集中型と分散型の2種類があります。
-
集中型バージョン管理システム (CVCS: Centralized Version Control System):
- Subversion (SVN), CVSなどが代表的です。
- すべての変更履歴が中央サーバーに一元管理されます。
- 開発者は中央サーバーからファイルをチェックアウトし、変更を加えてコミットすることでサーバーに反映させます。
- メリット: 管理が比較的容易、アクセス権限管理がしやすい。
- デメリット: 中央サーバーが停止すると、バージョン管理操作が一切できなくなる。開発者は常にネットワークに接続している必要がある。各開発者のローカルには最新の状態しか存在しないため、完全な履歴はサーバーに依存する。
-
分散型バージョン管理システム (DVCS: Distributed Version Control System):
- Git, Mercurialなどが代表的です。
- 各開発者が自身のローカル環境に、リポジトリ全体の完全な変更履歴を持ちます。
- 開発者はローカルでコミットを繰り返し、ある程度のまとまりになったら、リモートリポジトリ(他の開発者と共有するためのリポジトリ)にプッシュ(送信)します。他の開発者はリモートリポジトリから変更をプル(取得)します。
- メリット: オフラインでもコミットなどのバージョン管理操作が可能。中央サーバーがなくても、開発者同士でリポジトリを直接共有できる。履歴が分散しているため、サーバー障害に対する耐性が高い。マージ機能が強力。
- デメリット: 概念がCVCSよりやや複雑に感じられる場合がある。
Gitは分散型VCSであり、その設計思想がGitHubのようなプラットフォームでの共同開発モデル、特にプルリクエストの機能と非常に親和性が高いです。
2.3. Gitの仕組み:リポジトリ、コミット、ブランチ
Gitを理解するための核となる概念は、「リポジトリ」「コミット」「ブランチ」です。
-
リポジトリ (Repository): プロジェクトのファイルとその変更履歴全体を格納する場所です。ローカル環境に存在するものを「ローカルリポジトリ」、GitHubなどのサーバー上に存在するものを「リモートリポジトリ」と呼びます。リポジトリには、プロジェクトのコードだけでなく、Gitがバージョン管理のために使用するメタデータも含まれています。
-
コミット (Commit): リポジトリにおける変更履歴の最小単位です。ファイルの追加、削除、変更といった作業のスナップショットを記録したものです。各コミットには、以下のような情報が含まれます。
- 変更内容そのもの(どのファイルがどう変わったか)
- コミットした開発者(Author)
- コミット日時
- コミットメッセージ(なぜその変更を行ったかの説明)
- 親コミットへの参照(どのコミットの「次の」変更かを示す。これにより履歴が鎖のように繋がります)
コミットは、開発の「チェックポイント」のようなものです。機能の追加やバグ修正など、あるまとまった作業が完了したらコミットを行います。良いコミットメッセージを書くことは、後から履歴を見返したり、他の開発者が変更内容を理解したりする上で非常に重要です。
- ブランチ (Branch): 開発の分岐点を作成する機能です。リポジトリは一本の線状のコミット履歴として捉えることができますが、ブランチを使うことで、その線から枝分かれして並行して開発を進めることができます。
- 新しい機能開発やバグ修正を行う際に、メインの開発ライン(例えば
main
ブランチ)から新しいブランチを作成し、そのブランチ上で作業を進めるのが一般的なワークフローです。 - ブランチ上でコミットを重ねても、メインのブランチには影響しません。
- 作業が完了し、テストやレビューを経て問題がないことが確認できたら、そのブランチの変更内容をメインのブランチに統合(マージ)します。
- 新しい機能開発やバグ修正を行う際に、メインの開発ライン(例えば
ブランチを使うことの最大のメリットは、メインのコードを汚染することなく、独立した環境で自由に開発や実験が行えることです。問題が発生した場合でも、そのブランチを破棄すればメインのコードに影響はありません。プルリクエストは、まさにこの「ブランチで行った変更を、別のブランチ(通常はメインのブランチ)にマージしたい」という提案を行うための機能です。
2.4. GitとGitHubの関係
Gitはバージョン管理を行うための「ツール」であり、コマンドラインから操作したり、GUIクライアントを使用したりしてローカルで動作します。
一方、GitHubは、Gitリポジトリをホスティングする「サービス」です。Gitそのものの機能(コミット、ブランチなど)を提供しているわけではなく、開発者が作成したGitリポジトリをインターネット上で公開・共有するためのプラットフォームです。
GitHubは、単なるリポジトリホスティングにとどまらず、チーム開発を支援するための様々な付加機能を提供しています。その中には、以下のようなものがあります。
- プルリクエスト: ブランチ間の変更提案、コードレビュー、議論の場を提供します。(この記事の主題です!)
- Issue: タスク管理やバグ報告を行うための機能です。プルリクエストと連携させることができます。
- Wiki: プロジェクトに関するドキュメントを共有できます。
- Project boards: カンバン方式などでタスクの進捗を管理できます。
- Actions: CI/CD(継続的インテグレーション/継続的デリバリー)を実現するための自動化ワークフローを設定できます。
- Codespaces: クラウドベースの開発環境を提供します。
Gitはローカルでのバージョン管理を、GitHubはリモートでのリポジトリ共有とチーム開発支援機能を提供することで、開発プロセス全体を効率化しています。プルリクエストは、このGitHubが提供するチーム開発支援機能の中核をなすものです。
3. GitHubとプルリクエストの役割
Gitの基本的な概念を踏まえ、GitHubにおけるプルリクエストの役割をより深く理解しましょう。
3.1. GitHubとは
前述の通り、GitHubは世界中の開発者に利用されている、Gitリポジトリをホスティングするためのプラットフォームです。Microsoftが運営しており、個人プロジェクトから大規模なエンタープライズまで、幅広い用途で利用されています。
GitHub上にリポジトリを作成することで、自分のコードをインターネット経由で公開したり、他の開発者と共有したり、共同で開発を進めたりすることができます。オープンソースプロジェクトの多くはGitHub上で公開されており、誰でもコードを閲覧したり、コントリビュート(貢献)したりすることができます。
3.2. GitHubにおける共同開発のワークフロー
GitHubを使った一般的な共同開発のワークフローは以下のようになります。
- リポジトリの準備: プロジェクトのコードをGitHub上にリポジトリとして作成またはクローン/フォークします。
- フィーチャーブランチの作成: 新しい機能開発やバグ修正などの作業を行う際に、メインブランチ(
main
など)から作業用の新しいブランチ(フィーチャーブランチと呼びます)を作成します。 - ローカルでの開発: 作成したフィーチャーブランチ上で、コードの変更を行います。
- コミット: あるまとまった作業が完了したら、変更内容をコミットします。
- プッシュ: ローカルで行ったコミットを、GitHub上の自分のリモートリポジトリのフィーチャーブランチにプッシュします。
- プルリクエストの作成: GitHub上で、プッシュしたフィーチャーブランチの変更内容を、メインブランチにマージしてほしいという「プルリクエスト」を作成します。
- レビューと議論: チームの他の開発者がプルリクエストの内容を確認し、コードレビューを行います。フィードバックがあれば、プルリクエストの作成者はコードを修正し、再度プッシュします。
- CI/CDの実行: プルリクエストが作成・更新されるたびに、自動テストやビルドなどが実行され、変更がメインブランチに統合されても問題がないか確認されます。
- マージ: レビューが完了し、すべてのチェックが成功したら、プルリクエストを作成したブランチの変更内容をメインブランチにマージします。
- ブランチのクリーンアップ: マージが完了したフィーチャーブランチは、役割を終えたため削除します。
このワークフローにおいて、プルリクエストはステップ6から9までの中心的な役割を担います。単にコードをマージするだけでなく、その変更についてチーム全体で合意形成を図り、品質を担保するための「場」を提供するのです。
3.3. プルリクエストとは何か
プルリクエスト(Pull Request、略してPR)は、GitやGitHubにおける共同開発の核となる機能です。簡単に言うと、「私のブランチで行った変更を、あなた(リポジトリの管理者や他の開発者)のブランチ(例えばmain
ブランチ)にプル(取り込み)してほしい」というリクエスト(要求・提案)です。
技術的には、プルリクエストは特定のソースブランチ(例: feature/add-user-profile
)から特定のターゲットブランチ(例: main
)への変更の差分(diff)を示します。GitHubのプルリクエストページでは、この差分を分かりやすく表示し、その変更に関する以下の情報や機能を集約しています。
- 変更されたファイルの一覧と差分: どのファイルが追加・削除・変更され、具体的にコードのどの行がどう変わったかが色分けされて表示されます。
- 関連するコミット: プルリクエストに含まれるすべてのコミット履歴を確認できます。
- 会話(Conversation): プルリクエスト全体や特定のコード行に対するコメントを入力し、開発者間で議論を行うためのスレッド形式の掲示板です。
- レビュアー: 誰がこの変更をレビューする責任者かを示します。
- Checks: CI/CDツールによる自動テストやリンティングの結果が表示されます。
- マージボタン: レビューが完了し、マージ可能な状態になった場合に表示されるボタンです。
プルリクエストは、開発者にとって単なる機能ではなく、チームとのコミュニケーションの中心となるツールです。自分の変更内容を共有し、フィードバックを求め、議論を深めることで、より良いコードを作り上げるプロセス全体をサポートします。
3.4. プルリクエストが提供するメリット
プルリクエストをワークフローに取り入れることで、チームは以下のメリットを享受できます。
- コード品質の向上: 他の開発者によるレビューを受けることで、自分一人では気づけなかったバグ、非効率な実装、コーディング規約からの逸脱などを発見できます。また、「誰かに見られる」という意識が、より丁寧なコードを書くモチベーションにもつながります。
- 知識共有と学習: プルリクエストを通じたコードレビューや議論は、チームメンバー間の知識共有を促進します。新しく参加したメンバーが既存のコードベースを理解したり、経験の浅いメンバーが経験豊富なメンバーから学びを得たりする貴重な機会となります。
- 変更のリスク低減: メインブランチに直接コミットするのではなく、一度プルリクエストとして提案することで、変更内容がチームの合意と自動テストによる検証を経てから統合されます。これにより、意図しない変更が本番環境にデプロイされるリスクを大幅に低減できます。
- 透明性の向上: 誰がどのような目的で、どのようなコード変更を行っているのかがプルリクエストとして可視化されます。プロジェクト全体の進捗や、各メンバーの貢献度を把握しやすくなります。
- 追跡可能な履歴: プルリクエストに付随する議論やレビュー履歴は、コード変更の背景や意思決定のプロセスを示す重要な記録となります。後から特定の変更がなぜ行われたのかを知りたい場合に役立ちます。
- 自動化ワークフローとの連携: プルリクエストをトリガーとして、CI/CDパイプラインを自動実行できます。これにより、コードの整合性や品質を継続的にチェックし、デプロイプロセスを自動化する基盤となります。
これらのメリットを最大限に引き出すためには、単にプルリクエストを作成するだけでなく、チーム全体でプルリクエストを活用したレビュー文化を醸成することが重要です。
4. プルリクエスト作成の準備
実際にプルリクエストを作成する前に、いくつかの準備が必要です。
4.1. GitHubアカウントの作成
GitHubのサービスを利用するには、GitHubアカウントが必要です。まだお持ちでない場合は、GitHubのWebサイト(https://github.com/)にアクセスし、アカウントを作成してください。
4.2. Gitのインストールと初期設定
ローカル環境でGitコマンドを使用するために、Gitをインストールする必要があります。お使いのOS(Windows, macOS, Linux)に合わせて、Gitの公式Webサイト(https://git-scm.com/)からインストーラーをダウンロードしてインストールしてください。
インストール後、以下のコマンドでユーザー名とメールアドレスを設定します。これは、あなたがコミットした際に、そのコミットを誰が行ったかを示す情報となります。
bash
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
また、Gitのデフォルトブランチ名をmain
に設定しておくと、GitHubの新しいリポジトリのデフォルト名と一致するため便利です(Gitのバージョン2.28以降)。
bash
git config --global init.defaultBranch main
4.3. 対象リポジトリの準備
プルリクエストを作成するには、GitHub上のリポジトリが必要です。
-
新規リポジトリ作成: ゼロから新しいプロジェクトを始める場合は、GitHub上で新規リポジトリを作成します。作成時にREADMEファイルや.gitignoreファイル、ライセンスなどを追加することもできます。
-
既存リポジトリのフォーク (Fork) とクローン (Clone): 既存のプロジェクト(特にオープンソースプロジェクトなど、自分が管理者でないリポジトリ)に貢献したい場合は、「フォーク」という操作を行います。フォークとは、対象リポジトリのコピーを自分のGitHubアカウント内に作成することです。これにより、オリジナルのリポジトリに直接変更を加える権限がなくても、自分のフォークしたリポジトリで自由に開発を進めることができます。
GitHub上で対象リポジトリのページを開き、「Fork」ボタンをクリックします。
フォークした(または自分で作成した)リモートリポジトリを、今度はローカル環境に複製します。この操作を「クローン」と呼びます。クローンは、リモートリポジトリのすべてのファイルと履歴をローカルにコピーする作業です。
bash
git clone <リモートリポジトリのURL>リモートリポジトリのURLは、GitHub上のリポジトリページの「Code」ボタンをクリックすると確認できます。HTTPSまたはSSH形式のURLを使用できます。
クローンが完了すると、指定したディレクトリ名(通常はリポジトリ名)でディレクトリが作成され、その中にリポジトリの内容がコピーされます。このディレクトリがあなたのローカルリポジトリとなります。
ローカルリポジトリに入り、リモートリポジトリが正しく設定されているか確認しましょう。
bash
cd <クローンしたディレクトリ名>
git remote -v通常、
origin
という名前で、クローン元のリモートリポジトリ(フォークしたリポジトリなど)が設定されています。オリジナルリポジトリ(upstream)にプルリクエストを送る場合は、後でそのリモートも追加する必要があります。
4.4. ローカルでの開発環境設定
ローカルリポジトリの準備ができたら、開発に使用するエディターやIDEなどを設定します。特別なGitの準備というわけではありませんが、コードを書くための環境が必要です。
4.5. ブランチ戦略の概要とフィーチャーブランチの重要性
チーム開発を効率的に進めるためには、ブランチの使い方に関するルール、すなわち「ブランチ戦略」を定めることが一般的です。様々な戦略がありますが、最もシンプルで広く使われているのは、「メインブランチ」と「フィーチャーブランチ」を使う方法です。
- メインブランチ (例:
main
,master
): これはプロジェクトの最も安定した、あるいはリリース可能な状態を保持するブランチです。基本的には、このブランチに直接コミットすることは避けるべきです。プルリクエストを通じて、他のブランチからの変更のみをマージするように運用します。 - フィーチャーブランチ (Feature Branch): 新しい機能の実装、バグ修正、改善などの個別の作業を行うために、メインブランチから分岐して作成されるブランチです。各フィーチャーブランチは、一つの特定のタスクに集中して作業するために使用されます。作業が完了したら、このブランチをメインブランチにマージします。
なぜフィーチャーブランチで作業するのか?
- 分離: メインブランチに影響を与えることなく、独立した環境で作業できます。もしその作業がうまくいかなくても、メインブランチは影響を受けません。
- 並行開発: 複数の開発者がそれぞれ異なるフィーチャーブランチ上で、同時に異なる作業を進めることができます。
- コードレビューの単位: プルリクエストは通常、一つのフィーチャーブランチの変更内容をレビューの単位とします。これにより、レビュー範囲が限定され、レビューが効率的になります。
- 変更の管理: 各フィーチャーブランチが特定のタスクに対応するため、どの変更がどのタスクに関連しているかが明確になります。
プルリクエストは、このフィーチャーブランチで行った変更を、メインブランチに統合するプロセスそのものです。したがって、プルリクエストを作成する準備として、まずフィーチャーブランチ上で作業を進めることが非常に重要になります。
5. プルリクエストを作成するステップ
準備が整ったらいよいよプルリクエストを作成する具体的なステップに入ります。
5.1. ステップ1: 作業用ブランチ(フィーチャーブランチ)の作成
ローカルリポジトリで、作業を開始する前に、必ず新しいブランチを作成し、そこに切り替えてから作業を行います。通常、作業の起点となるのはメインブランチ(main
など)の最新の状態です。
まず、メインブランチにいることを確認し、リモートの最新状態を取得します。
bash
git checkout main # mainブランチに切り替え
git pull origin main # リモートの最新状態を取得
次に、新しいフィーチャーブランチを作成し、そのブランチに切り替えます。ブランチ名は、作業内容が分かりやすいように命名するのが一般的です(例: feature/add-user-profile
, fix/login-bug
, refactor/database-query
)。
bash
git branch feature/my-new-feature # 新しいブランチを作成
git checkout feature/my-new-feature # そのブランチに切り替え
または、以下のコマンドでブランチ作成と切り替えを一度に行うこともできます。
“`bash
git checkout -b feature/my-new-feature # ブランチを作成して切り替え
または Git 2.23以降では switch コマンドも利用可能
git switch -c feature/my-new-feature
“`
これで、あなたはfeature/my-new-feature
というブランチ上で作業を開始する準備ができました。このブランチ上で行う変更は、main
ブランチには影響しません。
5.2. ステップ2: コードの変更とコミット
新しいブランチに切り替えたら、目的とする機能実装やバグ修正などのコード変更を行います。
変更を加えたら、以下のコマンドで現在のリポジトリの状態を確認します。
bash
git status
git status
は、どのファイルが変更されたか、ステージングされているか、コミットされていないかなどを表示してくれます。
変更したファイルをコミットの対象(ステージングエリア)に追加します。特定のファイルのみを追加する場合はファイル名を指定し、すべての変更を追加する場合は.
を使用します。
bash
git add path/to/modified_file.rb # 特定のファイルを追加
git add . # すべての変更を追加
ステージングが完了したら、コミットを実行します。コミットには、その変更が何を目的としているのかを簡潔に説明する「コミットメッセージ」を添える必要があります。
bash
git commit -m "feat: add user profile page" # 例: コミットメッセージ付きでコミット
コミットメッセージは、以下の規約に従うと、履歴が読みやすくなります。
- 一行目(サマリー): 変更内容を簡潔に要約します(推奨文字数: 50文字以内)。動詞から始め、変更の目的を明確にします。
- 二行目: 空行を挟みます(必須)。
- 三行目以降(本文): 必要に応じて、変更の背景、詳細、技術的な選択の理由などを記述します(推奨文字数: 72文字以内/行)。
例:
“`
feat: Implement user profile page
Adds a new page at /users/{id} to display user details.
Includes fetching user data from the API and rendering
it in a responsive layout.
Resolves #123
“`
コミットは、ある一つの論理的な作業単位が完了するたびに行います。複数のコミットに分けて作業を進めることで、変更履歴が細分化され、後から特定の変更を探したり、問題を追跡したりしやすくなります。
5.3. ステップ3: リモートリポジトリへのプッシュ
ローカル環境でコミットを重ねて作業を進めたら、その変更内容をGitHub上のリモートリポジトリに反映させる必要があります。この操作を「プッシュ (Push)」と呼びます。
ローカルのfeature/my-new-feature
ブランチを、GitHub上のあなたのリモートリポジトリにプッシュします。
bash
git push origin feature/my-new-feature
このコマンドは、ローカルのfeature/my-new-feature
ブランチのコミット履歴を、origin
という名前で登録されているリモートリポジトリ(通常はあなたのフォークしたリポジトリや、チームの共有リポジトリ)の同じ名前のブランチに送信します。
初めてそのブランチをプッシュする場合、以下のコマンドでアップストリーム(追跡)ブランチを設定することを推奨されることがあります。
“`bash
git push -u origin feature/my-new-feature
または
git push –set-upstream origin feature/my-new-feature
“`
-u
または--set-upstream
オプションを付けてプッシュすると、次回以降はこのブランチでgit pull
やgit push
を実行する際に、どのリモートブランチと同期するかを毎回指定する必要がなくなります。(単にgit pull
やgit push
と打つだけで済みます)。
プッシュが成功すると、GitHub上のあなたのリポジトリにfeature/my-new-feature
ブランチが作成され、あなたがローカルでコミットした内容が反映されます。
5.4. ステップ4: GitHub上でプルリクエストを作成
ローカルでの作業をリモートリポジトリにプッシュしたら、いよいよGitHub上でプルリクエストを作成します。
- GitHubリポジトリページにアクセス: Webブラウザで、あなたのGitHubアカウントの対象リポジトリ(通常はあなたがフォークしたリポジトリ)のページにアクセスします。
- プルリクエスト作成の表示: GitHubは、あなたが新しくブランチをプッシュしたことを検知し、リポジトリページのトップに「Compare & pull request」というボタンや、「〇〇 branch had recent pushes…」のようなメッセージを表示することがあります。このボタンをクリックすると、プルリクエスト作成画面に直接遷移できます。もし表示されない場合は、「Pull requests」タブをクリックし、「New pull request」ボタンをクリックします。
-
比較ブランチとベースブランチの選択:
- プルリクエスト作成画面で、「base」と「compare」の2つのドロップダウンメニューが表示されます。
- base: これは、あなたの変更を取り込みたいターゲットブランチです。通常は、オリジナルリポジトリ(または共有リポジトリ)の
main
ブランチやdevelop
ブランチを選択します。 - compare: これは、あなたの作業用ブランチです。先ほどローカルで作業し、プッシュした
feature/my-new-feature
ブランチを選択します。 - あなたがフォークしたリポジトリからオリジナルリポジトリにプルリクエストを送る場合は、
base
にオリジナルリポジトリのブランチを、compare
にあなたのリポジトリのブランチを選択することになります。GitHubのUIで、リポジトリの選択肢も表示されます。
-
プルリクエストのタイトルと説明の入力:
- タイトル: プルリクエストの目的を簡潔かつ分かりやすく記述します。コミットメッセージの一行目と同様に、変更内容を要約します(例:
feat: ユーザープロフィールページを実装
)。 - 説明: 変更内容の詳細、背景、解決する課題、関連するIssue、実装上の注意点などを記述します。丁寧な説明は、レビュアーが変更内容を理解するのに役立ちます。Markdown記法が使用できます。
- プルリクエストテンプレート: チームで開発している場合、プルリクエスト作成時に自動的に表示されるテンプレートを設定していることがあります。これには、変更の概要、テスト方法、注意点などを記述する項目があらかじめ用意されており、記入漏れを防ぎ、レビューに必要な情報を網羅するのに役立ちます。テンプレートがあれば、それに従って記述しましょう。
- 関連するIssueへのリンク: そのプルリクエストが解決する、または関連するIssueがある場合は、本文中に
#<Issue番号>
(例:#123
)と記述することでリンクさせることができます。さらに、close #123
,fixes #123
,resolves #123
のようなキーワードを使ってIssue番号を記述すると、そのプルリクエストがマージされた際に、関連するIssueを自動的にクローズすることができます。
- タイトル: プルリクエストの目的を簡潔かつ分かりやすく記述します。コミットメッセージの一行目と同様に、変更内容を要約します(例:
-
レビュアー、ラベル、プロジェクトなどの設定:
- プルリクエスト作成画面の右側のサイドバーには、様々な設定項目があります。
- Reviewers: このプルリクエストをレビューしてほしいチームメンバーを指定します。レビュアーに指定されたメンバーには通知が届きます。
- Assignees: このプルリクエストを担当する人を自分または他のメンバーに指定します。
- Labels: プルリクエストの種類(例:
bug
,enhancement
,refactor
)、優先度(例:priority: high
)、ステータス(例:needs review
)などを分類するためのラベルを付けます。 - Projects: 開発プロジェクトのボードと関連付けます。
- Milestone: 特定のマイルストーン(開発期間の区切り)と関連付けます。
これらの設定を適切に行うことで、プロジェクトの管理やチーム内での情報共有がスムーズになります。
-
プルリクエストの送信: 必要な情報をすべて入力・設定したら、「Create pull request」ボタンをクリックしてプルリクエストを送信します。
5.5. ステップ5: プルリクエストページの確認
プルリクエストを作成すると、そのプルリクエスト専用のページが開きます。このページは、その変更に関するすべての情報が集約される場所です。主なタブと内容を確認しましょう。
- Conversation (会話): プルリクエストのタイトル、説明、関連するコミットの概要が表示され、プルリクエスト全体に関する議論が行われるメインのタブです。システムからの通知(プッシュ、CI/CDの実行結果など)もここに表示されます。レビューコメントもここに集約されます。
- Commits (コミット): このプルリクエストに含まれるすべてのコミット一覧が表示されます。各コミットをクリックすると、そのコミット単体での変更内容を確認できます。
- Files changed (ファイル変更): このプルリクエストに含まれる全てのコード変更の差分が表示されます。どのファイルが追加・削除・変更され、コードのどの行がどのように変わったかが、色分けされて(追加は緑、削除は赤)表示されます。コードレビューはこのタブで行われることがほとんどです。
- Checks (チェック): CI(継続的インテグレーション)ツール(GitHub Actions, Travis CI, CircleCIなど)と連携している場合、このプルリクエストに対して自動的に実行されたビルドやテストの結果が表示されます。すべてのチェックがパスしているかどうかが、マージの重要な条件となります。
プルリクエストを作成したら、これらのタブを確認し、変更内容が正しく反映されているか、自動チェックが実行されているかなどを確認しましょう。
6. プルリクエストのレビュープロセス
プルリクエストは、作成するだけでなく、レビューを受けることで真価を発揮します。
6.1. レビュアーの役割
レビュー担当者(レビュアー)は、プルリクエストの変更内容を技術的、論理的、規約的な観点から評価し、フィードバックを提供します。レビュアーの主な役割は以下の通りです。
- 変更内容の理解: プルリクエストの説明やコードを読み、なぜこの変更が必要なのか、どのような目的で実装されたのかを理解します。
- コードの品質評価: バグがないか、コードが読みやすいか、パフォーマンスに問題はないか、セキュリティ上の脆弱性はないかなどをチェックします。
- 設計の妥当性: 実装が設計意図に合っているか、将来的な拡張性や保守性を考慮しているかなどを評価します。
- コーディング規約の遵守: チームで定められたコーディング規約やスタイルガイドに従っているかを確認します。
- 関連Issueの確認: プルリクエストが関連するIssueを適切に解決しているかを確認します。
- フィードバックの提供: 発見した問題点、疑問点、改善提案などをコメントとしてプルリクエストページに記録します。
6.2. レビューの通知
プルリクエストが作成されると、リポジトリのウォッチ設定やチームの設定に応じて、関係者(特にレビュアーに指定された人)に通知が届きます。この通知を見て、レビュアーはプルリクエストの内容を確認しに行きます。
6.3. コードレビューの実施
レビュアーは、GitHub上のプルリクエストページを開き、主に「Files changed」タブでコードレビューを行います。
- ファイル変更タブでのレビュー: 「Files changed」タブには、変更されたファイルのリストと、それぞれのファイルにおけるコードの差分が表示されます。レビュアーはこの差分を見ながら、変更内容を理解し、評価します。
- 行に対するコメント: コードの特定の行に対してコメントを付けたい場合は、該当する行番号にマウスカーソルを合わせると表示される青い
+
ボタンをクリックします。コメントを入力し、「Add single comment」または「Start a review」を選択します。- Add single comment: その場ですぐにコメントが追加されます。簡単な質問や提案に使います。
- Start a review: レビューセッションを開始します。複数のコメントを一度にまとめて投稿する場合に使用します。「Add review comment」で複数のコメントを追加し、最後に「Finish your review」ボタンをクリックしてまとめて投稿します。この際に、レビューの結果(承認、変更要求、単なるコメント)を選択します。
- レビューコメントの種類:
- Comment: 単なるコメントや質問、またはまだレビューを完了しない場合に使用します。
- Approve: プルリクエストの内容を承認し、マージしても良いと判断した場合に選択します。マージに必要な承認数が設定されているリポジトリでは、これがマージの条件となります。
- Request changes: プルリクエストに修正が必要な箇所があると判断した場合に選択します。修正が完了するまでマージはブロックされます。修正内容をコメントで具体的に指示する必要があります。
レビューコメントは、プルリクエストの「Conversation」タブにも表示され、スレッド形式で議論を進めることができます。
6.4. 作成者によるフィードバックへの対応
プルリクエストの作成者は、レビュアーからのフィードバックを確認し、必要に応じてコードを修正します。
- コメントへの返信: GitHub上のコメントに対して、質問に答えたり、意図を説明したり、同意したりすることができます。建設的なコミュニケーションを心がけましょう。
- ローカルでのコード修正: フィードバックに基づいて、ローカルの作業用ブランチ(例:
feature/my-new-feature
)でコードを修正します。 - 新しいコミットとプッシュ: 修正が完了したら、再度
git add
とgit commit
で変更をコミットします。修正内容を示す分かりやすいコミットメッセージを付けましょう(例:fix: address review feedback on user profile validation
)。修正内容が前のコミットの訂正である場合など、履歴を整理したい場合はgit commit --amend
やgit rebase -i
といった操作を使うこともありますが、初心者には少し高度な操作です。単純に新しいコミットとして追加しても問題ありません。 -
変更がPRに自動的に反映される仕組み: ローカルでの修正をコミットしたら、再度同じブランチ名でリモートリポジトリにプッシュします。
bash
git push origin feature/my-new-featureGitHubは、対象のプルリクエストに関連付けられているブランチ(この場合は
feature/my-new-feature
)に新しいコミットがプッシュされたことを自動的に検知し、その変更内容を既存のプルリクエストに自動的に追加してくれます。つまり、一度プルリクエストを作成すれば、その後の修正は同じブランチにプッシュするだけで、プルリクエストの内容が更新されるのです。レビュアーは更新されたプルリクエストを見て、修正が正しく行われたかを確認できます。
6.5. コンフリクトの解決
複数の開発者が同時に同じファイルの同じ行を変更した場合など、「コンフリクト(Conflict)」が発生することがあります。これは、Gitがどちらの変更を採用すれば良いか自動的に判断できない場合に起こります。
- コンフリクト発生の原因:
- あなたが作業しているブランチと、マージ先のブランチ(例:
main
)で、同じファイルの同じ箇所が同時に変更された場合。 - あなたが作業を開始した後に、マージ先のブランチが更新され、その更新内容とあなたの変更内容が競合している場合。
- あなたが作業しているブランチと、マージ先のブランチ(例:
- GitHub上でのコンフリクト表示: プルリクエストを作成・更新した際にコンフリクトが発生している場合、GitHubのプルリクエストページに「This branch has conflicts that must be resolved」のようなメッセージが表示され、マージボタンが無効になります。
-
ローカルでのコンフリクト解決手順: コンフリクトは、基本的にはローカル環境で解決します。
- ローカルの作業用ブランチにいることを確認します (
git status
などで確認)。 -
マージ先のブランチ(例:
main
)の最新状態をローカルに取得します。もしフォークしたリポジトリで作業している場合は、まずオリジナルリポジトリをリモートとして追加し、そこから最新状態を取得する必要があります。“`bash
オリジナルリポジトリをupstreamとして追加(初回のみ)
git remote add upstream <オリジナルリポジトリのURL>
upstreamの最新状態を取得
git fetch upstream
ローカルのmainブランチを更新(必要に応じて)
git checkout main
git pull upstream main
``
main`)の最新状態をあなたのローカルリポジトリで取得し、それをあなたのフィーチャーブランチにマージします。
または、単にマージ元のブランチ(例:“`bash
マージ元のブランチの最新状態をローカルに取得
git checkout main # または対象のベースブランチ
git pull origin main # あるいは git pull upstream main作業中のフィーチャーブランチに戻り、最新のmainブランチを取り込む
git checkout feature/my-new-feature
git merge main # または git merge upstream/main
“` -
git merge main
を実行した際にコンフリクトが発生すると、Gitはコンフリクトが発生したファイルを教えてくれます。これらのファイルを開くと、コンフリクトマーカー(<<<<<<<
,=======
,>>>>>>>
など)によって、どちらのブランチの変更が競合しているかが示されています。 - 手動でファイルを編集し、どちらの変更を採用するか、あるいは両方の変更をどのように組み合わせるかを決定して、コンフリクトマーカーを削除します。
-
コンフリクトを解決したファイルをステージングエリアに追加します。
bash
git add path/to/conflicted_file -
コンフリクト解決のためのコミットを行います。Gitが自動的にコミットメッセージを生成してくれますが、必要に応じて編集できます。
bash
git commit # エディターが起動し、コミットメッセージを編集できます -
コンフリクトを解決した作業用ブランチを、再度リモートリポジトリにプッシュします。
bash
git push origin feature/my-new-feature
プッシュ後、GitHub上のプルリクエストページでコンフリクトが解決されたことが表示され、マージボタンが有効になります。
- ローカルの作業用ブランチにいることを確認します (
7. プルリクエストのマージ
レビューが承認され、すべての自動チェックがパスし、コンフリクトも解決されたら、いよいよプルリクエストをマージできます。
7.1. マージの条件
多くの場合、プルリクエストをマージするためにはいくつかの条件を満たす必要があります。これらはリポジトリの設定(Branch protection rules)で強制することができます。一般的な条件は以下の通りです。
- レビュー承認: 少なくとも1人(または指定された人数)のレビュアーが「Approve」していること。
- 変更要求がないこと: 誰からも「Request changes」が出されていないこと、あるいは出された変更要求にすべて対応済みであること。
- ステータスチェックのパス: CI/CDによる自動テストやリンターなどのステータスチェックがすべて成功していること。
- コンフリクトがないこと: マージ先のブランチとの間でコンフリクトが発生していないこと。
これらの条件が満たされると、GitHub上のプルリクエストページの下部にマージボタンが表示され、有効になります。
7.2. マージの種類
GitHubはプルリクエストをマージする際に、いくつかの方法を提供しています。それぞれの方法は、マージ後のコミット履歴の見え方が異なります。
-
Create a merge commit (マージコミットを作成):
- これがGitHubのデフォルトのマージ方法です。
- ソースブランチ(作業用ブランチ)のすべてのコミット履歴をそのまま残し、さらにベースブランチ(マージ先)に取り込んだことを示す新しい「マージコミット」を作成します。
- コミット履歴は、作業用ブランチからの分岐とそのマージが明確に示されるため、開発の経緯を詳細に追跡しやすいというメリットがあります。
- デメリットとしては、短いブランチで多くの小さなコミットを繰り返した場合など、履歴が複雑になりがちです。
- ローカルで
git merge <branch_name>
を実行するのとほぼ同じ結果になります。
-
Squash and merge (スカッシュしてマージ):
- ソースブランチ上の複数のコミットを、単一の新しいコミットにまとめ(スカッシュ)、それをベースブランチにマージします。
- 作業用ブランチでの細かい「途中の」コミット履歴を隠蔽し、プルリクエスト全体を「一つの論理的な変更」として記録したい場合に有効です。これにより、マージ後の履歴がシンプルで分かりやすくなります。
- 例えば、「実装の途中経過を示すコミット」や「タイポ修正コミット」などが複数あった場合、それらを一つの「〇〇機能実装」というコミットにまとめることができます。
- デメリットとしては、スカッシュされたコミットの詳細な履歴(誰がいつ、具体的に何を変更したか)が失われます。
- 新しいコミットがベースブランチに作成され、そのコミットメッセージはプルリクエストのタイトルと説明を基に生成されることが多いです。
-
Rebase and merge (リベースしてマージ):
- ソースブランチのコミット履歴を、ベースブランチの最新コミットの直後に「付け替え(リベース)」た上で、ファストフォワードマージ(単にポインタを進めるだけ)を行います。
- これにより、コミット履歴が一本の直線のように見えます。作業用ブランチからの分岐やマージコミットは作成されず、あたかも最初からベースブランチ上で作業していたかのような履歴になります。
- 履歴を非常にシンプルに保ちたい場合に有効です。
- デメリットとしては、コミットのハッシュ値が変更されるため、注意が必要です。また、チームで共通のブランチに対して安易にリベースを行うと、他のメンバーが困る可能性があるため、使い所を理解しておく必要があります(プルリクエストのマージ時にGitHubがRebase and mergeとして提供する機能は、ローカルでのリベースとは挙動が少し異なりますが、結果として履歴が一本線になるという点は同じです)。
- これもまた、ソースブランチの元のコミット履歴はベースブランチには取り込まれません(変更内容を持つ新しいコミットが作成されます)。
どのマージ方法を選択するかは、チームのブランチ戦略や履歴管理に関する方針によります。多くのチームでは、デフォルトの「Create a merge commit」か「Squash and merge」が利用されます。
7.3. マージボタンのクリック
マージの条件が満たされ、どのマージ方法を選択するか決まったら、GitHub上のプルリクエストページに表示されるマージボタンをクリックします。マージ方法を選択するためのドロップダウンメニューが表示される場合があります。
マージが完了すると、プルリクエストはクローズされ、作業用ブランチの変更内容がベースブランチに統合されます。
7.4. マージ後のブランチの扱い
プルリクエストがマージされると、そのプルリクエストの目的を達成した作業用ブランチは、通常はもう不要になります。GitHubは、プルリクエストがマージされた後に、元の作業用ブランチを削除することを推奨するボタンを表示してくれます。
ブランチを削除することで、リポジトリ内のブランチリストを整理し、混乱を防ぐことができます。マージされた変更はベースブランチの履歴に残っているので、作業用ブランチを削除しても変更内容が失われるわけではありません。
ローカルの作業用ブランチも、プルリクエストがマージされ、リモートのブランチが削除されたら、削除して構いません。
bash
git branch -d feature/my-new-feature # ローカルブランチを削除
-d
オプションは、マージ済みのブランチのみを削除します。マージされていない変更があるブランチを削除しようとすると警告が出ます。強制的に削除する場合は-D
オプションを使用します(ただし、未マージの変更は失われるので注意が必要です)。
8. プルリクエストのベストプラクティス
プルリクエストを効果的に活用するために、いくつかのベストプラクティスを紹介します。
- PRを小さく保つ: 一つのプルリクエストに含める変更範囲は、できるだけ小さく保ちましょう。一つの機能追加やバグ修正など、明確な一つの目的を持つ変更のみを含めるようにします。PRが小さいほど、レビュアーは変更内容を把握しやすく、レビューにかかる時間も短縮されます。レビューが迅速に行われることで、開発サイクル全体も高速化します。
- 明確なタイトルと説明を書く: プルリクエストのタイトルと説明は、レビュアーが最初に見る情報です。何のための変更なのか、どのような課題を解決するのかを簡潔かつ分かりやすく記述しましょう。テンプレートを活用するのも良い方法です。
- 関連するIssueやドキュメントにリンクする: もし関連するIssueや、その変更の背景にある設計ドキュメントなどがある場合は、プルリクエストの説明にリンクを貼りましょう。これにより、レビュアーはより深い文脈を理解できます。
- 自分でレビューする: プルリクエストを作成する前に、一度自分で「Files changed」タブを開いて変更内容を確認してみましょう。自分でレビューすることで、タイポや単純なミスに気づいたり、レビュアーに分かりにくい箇所を発見したりすることができます。
- 迅速にフィードバックに対応する: レビュアーからコメントや変更要求があったら、できるだけ早く対応しましょう。疑問点があれば質問し、修正が必要であればローカルでコードを修正して再度プッシュします。レビューが停滞すると、開発全体のボトルネックになります。
- 敬意を持ってコミュニケーションする: プルリクエストの議論やレビューコメントでは、建設的かつ敬意を持ったコミュニケーションを心がけましょう。フィードバックはコードに対するものであり、個人攻撃ではないことを理解し、冷静に対応することが重要です。
- 自動チェックを活用する: CI/CDパイプラインが設定されている場合は、その結果を注意深く確認しましょう。テストやリンターのエラーがあれば、マージ前に必ず修正します。
- ** WIP (Work In Progress) PRを活用する:** まだ作業途中だが、早期にフィードバックが欲しい場合や、チームメンバーに作業の進捗を共有したい場合は、タイトルに
[WIP]
やDraft
と付けてプルリクエストを作成することができます。GitHubでは「Draft Pull Request」という機能もあります。これはマージができない状態であることを示し、完成したら通常のプルリクエストに変換します。
これらのベストプラクティスを実践することで、プルリクエストのプロセスがよりスムーズになり、チーム全体の開発効率とコード品質が向上します。
9. まとめ
この記事では、GitHubプルリクエストの基本的なやり方について、その背景となるバージョン管理の概念から、プルリクエスト作成の準備、具体的なステップ、レビュープロセス、マージ、そしてベストプラクティスに至るまで、詳細に解説しました。
GitとGitHubを使った共同開発において、プルリクエストは単なるコード統合の手段ではなく、コードレビュー、議論、自動テスト連携など、開発プロセス全体を支える中心的なツールです。プルリクエストを適切に活用することで、コードの品質が向上し、チーム内のコミュニケーションが活性化し、プロジェクトの透明性が高まります。
初めてプルリクエストを作成する際は、少し難しく感じるかもしれませんが、この記事で紹介したステップを一つずつ実行してみてください。慣れてくれば、プルリクエストがチーム開発に不可欠な、強力なツールであることが実感できるはずです。
継続的にプルリクエストを使い、チームメンバーと積極的にコミュニケーションを取りながら、GitHubを使った共同開発を楽しんでください。そして、GitHubの公式ドキュメントや、チームの具体的なワークフローに関するドキュメントも参考にしながら、さらに理解を深めていくことをお勧めします。
これで、あなたはGitHubプルリクエストを使った共同開発の世界に一歩を踏み出す準備ができました。Happy Coding and Collaborating!