プルリクエストとは:作り方・レビュー・マージの流れ

公開 更新 書いた人 大林 諒

制作会社から「プルリクエストを出したので見てください」と連絡が来て、何を見ればいいのか分からないまま承認を押している人は少なくありません。AIに直してもらった変更が、同じ形で届くことも増えました。この記事では、小さな料理教室の料金表の修正を例に、プルリクエストの作り方、レビューで見るところ、マージまでを1周します。読み終わると、コードが読めなくても自分で判断できる範囲と、外注先に任せる範囲の線が引けます。

この記事の内容
  1. 先に答えると
  2. まず言葉をそろえる
  3. 料理教室の流れを1周する
  4. コードが読めなくても見られるところ
  5. マージの3つの方法
  6. AIが作ったプルリクエストの見方
  7. main への直接pushを止める(ブランチ保護)
  8. できないことと、その代わり
  9. よく詰まるところ
  10. 次に読む

先に答えると

プルリクエスト(Pull Request、PR)は「この枝を本筋に入れていいですか」という確認依頼です。Git本体の機能ではなく、GitHubの画面の上にある機能で、GitLabでは同じものを Merge Request と呼びます。変更した人が依頼を出し、別の人が差分を見てコメントし、問題がなければ本筋に合流させます。

  • 作るのは1分で済みます。枝をpushすると出る「Compare & pull request」を押し、題名と説明を書きます
  • 見るのは「Files changed」です。コードが読めなくても、文言・金額・電話番号・関係ないファイルが混ざっていないかは判断できます
  • 返事は Comment、Approve、Request changes の3種類です
  • マージの方法は3つありますが、迷ったら「Create a merge commit」で足ります
  • 非公開リポジトリで main への直接pushを止める機能(ブランチ保護)は、Organization なら2026年11月時点でTeam以上です。Freeでは公開リポジトリにしか使えません

まず言葉をそろえる

プルリクエストの話には、Gitの用語がいくつか同時に出てきます。ここで使う言葉は次の5つだけです。

言葉意味サンプル料理教室の例
リポジトリファイルと変更履歴を入れておく場所sample-cooking/website(非公開のホームページ)
コミット変更に名前をつけて履歴に残したひとまとまり「夏の教室を追加」
ブランチ(枝)本筋から分かれて作業する線add-summer-class
main公開しているものの元になる本筋の枝今のホームページの中身
マージ枝の変更を別の枝に合流させることadd-summer-class を main に入れる

Gitには git merge という合流のコマンドがあるだけで、「確認を頼む」「コメントする」「承認する」という機能はありません。そこを担当するのがGitHubのプルリクエストです。GitLabのMerge Requestも役割は同じで、画面の名前が違うだけと考えて読めます。

登場するのは代表と、制作会社の担当である外注エンジニアBの2人です。代表は料金と文言の責任者で、コードは読めません。Bが夏の教室のページを追加する依頼を受けたところから始めます。

料理教室の流れを1周する

全体は6段階です。誰がどこで手を動かすかを先に見ておくと、自分の番がはっきりします。

段階誰がどこでやること
1B手元のGit枝を作ってコミットしてpush
2BGitHubの画面プルリクエストを作り、代表をレビュアーに指定
3代表Files changed差分を見てコメント
4B手元のGit直して同じ枝にpush
5代表Review changesApprove
6代表かBConversationマージして枝を消す
プルリクエストの6段階の流れ
プルリクエストの6段階の流れ

枝を作ってpushする

Bの手元で実際に動かした内容です。送り先はこの記事のために手元に作った練習用の場所なので To の行が ../website.git になっていますが、GitHubならここがGitHubのURLになります。

$ git switch -c add-summer-class
Switched to a new branch 'add-summer-class'

$ git add menu.html index.html

$ git commit -m "夏の教室を追加"
[add-summer-class 98eb472] 夏の教室を追加
 2 files changed, 3 insertions(+), 1 deletion(-)

$ git push -u origin add-summer-class
To ../website.git
 * [new branch]      add-summer-class -> add-summer-class
branch 'add-summer-class' set up to track 'origin/add-summer-class'.

ここまではGitの操作で、main にはまだ何も入っていません。ホームページも変わりません。

プルリクエストを作る

GitHubの画面に移ります。

  1. リポジトリのトップを開く
  2. ファイル一覧の上の黄色い帯にある「Compare & pull request」を押す
  3. base(合流先)が main、compare(持ち込む枝)が add-summer-class になっているか確かめる
  4. 題名と説明を書く
  5. 「Create pull request」を押す

説明に書くのは、何を変えたか、なぜ変えたか、どこを見てほしいかの3点で足ります。「8月の夏の教室を料金表とトップに追加しました。料金7,000円で合っているか見てください」くらいの短さで十分です。

まだ途中の段階で見せたいときは、ボタンの横の下向き矢印から「Create Draft Pull Request」を選ぶと下書きとして出せます。下書きはマージできません。ただし料金ページでは下書きのプルリクエストはFreeだと公開リポジトリだけの扱いです(2026年11月時点)。

コマンドで作る方法もあり、GitHub CLI(gh)なら gh pr create --title "夏の教室を追加" --reviewer ユーザー名 です。

pushのあとに出る Compare & pull request のボタン
pushのあとに出る Compare & pull request のボタン

レビュアーを指定する

作成後の画面の右側に「Reviewers」があります。押してユーザー名を入力し、代表を選ぶと通知が飛びます。頼むにはリポジトリの書き込み権限が要り、頼まれる側は読み取り権限があれば足ります。

差分を見てコメントする

代表の番です。通知のリンクからプルリクエストを開き、「Files changed」を押します。同じ中身を手元で出すと次のようになります。行の頭の - が消えた行、+ が増えた行です。

$ git diff main...origin/add-summer-class
diff --git a/index.html b/index.html
index afe9158..35cd21c 100644
--- a/index.html
+++ b/index.html
@@ -1,2 +1,3 @@
 <h1>サンプル料理教室</h1>
 <p>月に4回、少人数で開いている料理教室です。</p>
+<p>8月は夏の教室を開きます。</p>
diff --git a/menu.html b/menu.html
index f15fe55..e8be344 100644
--- a/menu.html
+++ b/menu.html
@@ -1,7 +1,8 @@
 <h1>料金表</h1>
 <table>
-<tr><td>和食の基本</td><td>6,000円</td></tr>
+<tr><td>和食の基本</td><td>6,500円</td></tr>
 <tr><td>家庭の洋食</td><td>6,500円</td></tr>
 <tr><td>親子パン教室</td><td>4,800円</td></tr>
+<tr><td>夏の教室(8月限定)</td><td>7,000円</td></tr>
 </table>
 <p>お問い合わせ: 03-0000-0000</p>

夏の教室を足してほしいだけなのに、和食の基本が6,000円から6,500円に変わっています。タグの意味が分からなくても、これは見つけられます。

コメントは次の手順で付けます。

  1. 気になる行にマウスを乗せ、行番号の横に出る青いプラスを押す
  2. 「和食の基本は6,000円のままにしてください」と書く
  3. 「Start a review」を押す
  4. 画面上の「Review changes」を押す
  5. 全体へのひとことを書き、「Request changes」を選ぶ
  6. 「Submit review」を押す

3の時点ではコメントは本人にしか見えません。6まで押して初めてBに届きます。

Files changed の画面で差分を読む
Files changed の画面で差分を読む

3種類の返事の意味は次のとおりです。

選択肢意味使う場面
Comment承認も差し戻しもしない意見質問、感想
Approve入れてよいという承認見終わって問題がない
Request changes直してから入れてほしいという依頼金額の間違いなど

Request changes はブランチ保護などのルールを設定していなければ、お知らせの扱いです。押してもマージのボタンは止まりません。

Review changes の3つの選択肢
Review changes の3つの選択肢

直して同じ枝にpushする

Bは新しいプルリクエストを作りません。同じ枝に追加でコミットしてpushすると、開いているプルリクエストにそのまま載ります。

$ git add menu.html

$ git commit -m "和食の基本の料金を元に戻す"
[add-summer-class 9232046] 和食の基本の料金を元に戻す
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git push
To ../website.git
   98eb472..9232046  add-summer-class -> add-summer-class

差分を見直すと、和食の基本の行は変更なしに戻り、夏の教室の行だけが増えた形になります。

大きく直したあとにもう一度見てもらうときは、Reviewers の名前の横にある回転矢印のアイコンで再依頼します。行単位の修正案をボタンで取り込む「Commit suggestion」という機能もありますが、最初のうちは使わなくていいです。文章で頼めば足ります。

承認してマージする

代表がもう一度見て、Review changes から Approve します。次に Conversation の一番下で操作します。

  1. 「Merge pull request」を押す
  2. 「Confirm merge」を押す
  3. 「Delete branch」を押す

Delete branch は、合流が済んで要らなくなった枝を消すボタンです。消しても履歴は main に残っていて、同じ場所の「Restore branch」で戻せます。マージできるのは Organization のリポジトリの権限でいうと Write 以上の人です。

手元の枝はGitHubで消しても残ります。手元の片付けは次のとおりです。

$ git switch main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

$ git pull
From ../website
   b6bca39..c598a24  main       -> origin/main
Updating b6bca39..c598a24
Fast-forward
 index.html | 1 +
 menu.html  | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

$ git branch -d add-summer-class
Deleted branch add-summer-class (was 9232046).

$ git fetch --prune
From ../website
 - [deleted]         (none)     -> origin/add-summer-class

コードが読めなくても見られるところ

プルリクエストのタブのうち、代表が使うのは次の4つです。

タブ出ているもの代表が見ること
Conversation説明、やり取り、レビューの履歴頼んだ内容と説明が合っているか、未回答の質問がないか
Commits枝のコミットの一覧関係なさそうな題名が混ざっていないか
Checks自動テストなどの結果失敗が残っていないか
Files changed変更の差分下の4点

Files changed で見るのは次の4点です。

  • 変わったファイルの数と名前。料金表の修正なのに send_mail.py や .env が入っていたら止めます
  • 文言と金額。ここは代表が一番詳しく、Bより確実に見つけられます
  • 電話番号、住所、日付。消えた赤い行と増えた緑の行を並べて読みます
  • 頼んでいないのに変わった行。悪意がなくても、整形のついでや作業のついでで混ざります

見終わったファイルはヘッダーの右の「Viewed」を選ぶと畳めます。あとからそのファイルが変わると、印は自動で外れます。差分は左右に並べる split 表示にも切り替えられ、変更前と変更後を比べるときに読みやすくなります。

逆に、スクリプトの処理が正しいか、セキュリティ上問題ないかは代表の範囲を超えます。実際に運用していると、そこまで判断しようとして手が止まることのほうが問題です。「文言と金額は見ました。処理の中身は確認済みですか」とコメントで聞けば、役割は果たせます。

マージの3つの方法

Merge pull request のボタンの横の矢印を開くと3つ出ます。結果の違いは main の履歴の形です。リポジトリの設定によっては出ない方法もあります。

画面の名前main の履歴向いている場面
Create a merge commit枝のコミットが全部残り、合流の印のコミットが1つ増える迷ったらこれ。途中の修正も残したいとき
Squash and merge枝のコミットを1つにまとめて入れる途中のコミットが細かくて多い短い枝
Rebase and merge枝のコミットを main の先に1つずつ並べ直す一直線の履歴にそろえる決まりがあるとき

同じ枝を手元のGitで3通りに合流させて、結果を比べました。ボタンの中身そのものではありませんが、形は同じです。合流前は次の状態で、main には代表の電話番号の修正が先に入っています。

$ git log --oneline --graph --all
* 9232046 和食の基本の料金を元に戻す
* 98eb472 夏の教室を追加
| * c5ddbf0 問い合わせの電話番号を修正
|/  
* b6bca39 最初の版

Create a merge commit の形です。どの修正がどの枝から来たかが残ります。

$ git merge --no-ff -m "夏の教室を追加(プルリクエスト #1)" add-summer-class
Auto-merging menu.html
Merge made by the 'ort' strategy.
 index.html | 1 +
 menu.html  | 1 +
 2 files changed, 2 insertions(+)

$ git log --oneline --graph
*   c598a24 夏の教室を追加(プルリクエスト #1)
|\  
| * 9232046 和食の基本の料金を元に戻す
| * 98eb472 夏の教室を追加
* | c5ddbf0 問い合わせの電話番号を修正
|/  
* b6bca39 最初の版

Squash and merge の形です。金額を間違えて直した経緯は main からは見えなくなります。

$ git merge --squash add-summer-class
Auto-merging menu.html
Automatic merge went well; stopped before committing as requested
Squash commit -- not updating HEAD

$ git commit -m "夏の教室を追加(#1)"
[main 67a70b8] 夏の教室を追加(#1)
 2 files changed, 2 insertions(+)

$ git log --oneline --graph
* 67a70b8 夏の教室を追加(#1)
* c5ddbf0 問い合わせの電話番号を修正
* b6bca39 最初の版

Rebase and merge の形です。一直線になりますが、98eb472 が 02bcee3 に変わったように、コミットの番号が変わります。GitHubのボタンの場合、コミットした人の情報も更新され、番号は必ず新しくなります。

$ git log --oneline --graph
* ed3a92f 和食の基本の料金を元に戻す
* 02bcee3 夏の教室を追加
* c5ddbf0 問い合わせの電話番号を修正
* b6bca39 最初の版

迷ったら Create a merge commit を選びます。何も消えず、番号も変わらないので、あとから誰がいつ何を入れたかを追えます。AIと作業してコミットが細かく増えすぎるようになったら、Squash and merge に切り替えれば十分です。Rebase and merge は決まりがなければ使わなくていいです。

マージの方式を選ぶメニュー
マージの方式を選ぶメニュー

AIが作ったプルリクエストの見方

Claude Code や GitHub Copilot のようなAIは、きれいな説明文つきのプルリクエストを作ります。読みやすいので、そこで安心しがちです。見る順番は人の場合と変えません。

  • 説明文を根拠にしない。「料金表だけ修正しました」と書いてあっても、Files changed のファイル数を先に見ます
  • 頼んでいない行を探す。AIは周りまで整えることがあります。差分が多すぎたら「料金の行だけにしてください」と返します
  • テストの結果を画面で見る。Checks が失敗していないかを確かめます。テストの仕組みを入れていないリポジトリでは Checks タブには何も出ません。緑がないのは「通った」ではなく「何も調べていない」です
  • 説明文の「動作確認済み」を確かめる。AIが確かめた範囲を聞き、ホームページなら変更後の表示を自分の目で見ます
  • 自分で作ったプルリクエストは自分で Approve できません。代表がAIに作らせて自分で出した場合は、Bに見てもらうか、差分を見たうえで自分でマージします。次の節のように承認を必須にしたら、2人目の承認が要ります

main への直接pushを止める(ブランチ保護)

プルリクエストはお願いの仕組みなので、設定しなければ main に直接pushできてしまいます。それを止めるのがブランチ保護です。Force push(履歴を上書きする送信)も止まります。

使えるかどうかはプランで決まります。次の表は Organization の場合で、2026年11月時点の公式の記載です。個人アカウントのプランは含めていません。

Organization のプラン公開リポジトリ非公開リポジトリ
Free使える使えない
Team(1ユーザー月 $4)使える使える
Enterprise(1ユーザー月 $21)使える使える

sample-cooking/website は非公開なので、Freeのままだと保護できません。必須のレビュアー、変更箇所ごとの担当者を決める code owners も、Organization の非公開リポジトリではTeamの機能です。

Teamなら、管理者権限で次の手順で設定します。

  1. リポジトリの「Settings」を開く
  2. 左の「Branches」を押す
  3. 「Add classic branch protection rule」を押す
  4. 「Branch name pattern」に main と入れる
  5. 「Require a pull request before merging」を選び、「Require approvals」で必要な承認の数を1にする
  6. 管理者も対象にするなら「Do not allow bypassing the above settings」を選ぶ
  7. 「Create」を押す

6を選ばないと、管理者権限を持つ人にはルールが効きません。代表が管理者なら、代表だけ素通りできる状態になります。

できないことと、その代わり

できないことその代わり
Freeの Organization の非公開リポジトリで main を保護するTeamに上げるか、「main に直接pushしない」を決めごとにして運用する。機械では止まらない
Freeの非公開リポジトリで下書きのプルリクエストを出す題名に「作業中」と書き、マージしない約束にする

無料のまま保護を効かせたいなら、GitLabという選択肢もあります。GitLabは全プランでブランチ保護が使え、既定の枝は最初から保護されています。ただしFreeの承認は任意で、承認がなくてもマージできます。承認を必須にするのは Premium(1ユーザー月 $29、年額請求)以上です。プルリクエストのためだけに移るほどの話ではないので、移行は他の事情と合わせて考えます。

よく詰まるところ

症状原因直し方
「Compare & pull request」が出ない帯が消えた、push前、別の枝を見ている「Pull requests」タブの「New pull request」から枝を選ぶ
Merge pull request が押せないコンフリクトか、ルールの条件が足りないコンフリクトなら解消する。下書きならレビュー可能にする
書いたコメントがBに届いていないStart a review のまま送信していないReview changes から Submit review を押す
自分のプルリクエストを Approve できない作成者は自分のものを承認できない別の人に頼む。承認が必須なら2人目の権限が要る
Request changes したのにマージされた保護ルールがないとお知らせ扱いマージ前に見る約束にするか、Teamでブランチ保護を入れる
差分に大量の行が出る整形や改行コードの違いが混ざったFiles changed で空白の変更を無視する表示にし、関係ない変更は分けてもらう
差分が表示されない変更が大きすぎて上限を超えた小さく分けてもらう
git branch -d でエラーになるSquash and merge すると手元のコミットと番号が一致しないmain に入ったのを画面で確かめて git branch -D で消す

最後の表示は次のとおりです。Squash and merge のあと、GitHub側の枝を消して git fetch --prune まで済ませた状態で出ます。

$ git branch -d add-summer-class
error: the branch 'add-summer-class' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D add-summer-class'
hint: Disable this message with "git config set advice.forceDeleteBranch false"

$ git branch -D add-summer-class
Deleted branch add-summer-class (was 0e0faf6).

Squash and merge したあと、同じ枝を使い続けるのも避けます。次のプルリクエストに取り込み済みのコミットが混ざり、コンフリクトが起きやすくなります。

次に読む

枝の作り方と合流の基本は「git branchとmergeの使い方:枝を分けて合流する、GitHub Flowまで」にあります。Merge pull request が押せないときは「コンフリクトの直し方:起きる理由と、解消の手順」を開きます。誰にどの権限を渡すかは「GitHubの権限と2段階認証:共同作業者・Organization・非公開リポジトリ」、AIと一緒に使うときの全体の流れは「GitHub CopilotとClaude Code:AIでコードを書くときのGitの使い方」で続けます。

やることの一覧とプルリクエストを繋ぐ話は「GitHub IssuesとProjectsの使い方:やることを管理する」にあります。

あわせて読む