GitHub の画面との対応 — プルリクエスト
GitHub のリポジトリの画面に並んでいるもの(ファイルの一覧、main ▼ のボタン、「3 Commits」の数、コミットの短い ID)は、どれも GitHub 側のグラフの一部を見せています。この回では、画面の部品がグラフのどこに当たるかを確かめてから、プルリクエストを「ブランチ同士のマージの依頼」として読み解きます。GitHub の画面で Merge pull request を押すと GitHub 側のグラフだけが変わること、手元を追いつかせるには 2-3 の fetch と pull --ff-only を使うことを、1コマンドずつ見ていきます。
- 左の上のターミナルは、実際に打ったときと同じ出力です(Git は英語で答えます)
- その下に、グラフが2つ並びます。上が GitHub 側、下が手元です。同じコミットは、上と下で同じ横の位置に来ます
- 手元のグラフの点線の札
origin/mainは、手元に貼ってある GitHub 側の付箋の写しです。fetch や push をしたときにだけ、GitHub 側に合わせて貼り直されます - GitHub の画面で起きたこと(ボタンを押したなど)は、ターミナルには何も出ず、上の GitHub 側のグラフだけが変わります
- 右の説明をスクロールして読み進めると、左のターミナルでコマンドが1つずつ打たれます。
→キーでも1つずつ進みます(←で1つ戻ります。スマホでは「次へ」ボタン)。黄色く光っているのが、そのコマンドで変わった場所です
1. リポジトリの画面は、GitHub 側のグラフのどこか
ここまでの3回で、GitHub 側にもグラフ(コミットと付箋)があり、手元はその写しを origin/main として持っている、という形を見てきました。GitHub のリポジトリの画面は、その GitHub 側のグラフを、1つのブランチから見た姿です。
| 番号 | 画面の部品 | GitHub 側のグラフでは | 手元で同じものを見るなら |
|---|---|---|---|
| 1 | ブランチの切り替え(main ▼) | GitHub 側の付箋の一覧。選んだ付箋が、ほかの部品すべての起点になる | git branch -r(写しの一覧) |
| 2 | Code タブのファイルの一覧 | 選んだブランチの先頭のコミットの中身。最初は既定のブランチ(main) | そのブランチに switch して ls |
| 3 | 「3 Commits」の数 | そのブランチの付箋から親を辿れるコミットの数 | git log --oneline origin/main の行数 |
| 4 | 最新コミットの行の英数字 | 先頭のコミットの短い ID(本物は40桁で、頭の7桁を見せている) | git log --oneline -1 の先頭 |
「3 Commits」のような表示の言葉や置き場所は、GitHub の画面が変わるたびに少しずつ動きます。それでも、数えているものは変わりません。どの部品も、選んでいる付箋から辿った結果なので、main ▼ を memo に切り替えると、ファイルの一覧も数も ID も一斉に memo のものに変わります。
手元のコマンドで、この対応を確かめます。2-2 で作った作業用ブランチ memo(notes.txt を足した2つのコミット)を push するところから始めます。
GitHub のリポジトリの画面と、GitHub 側のグラフ
2-2 の続きです。作業用ブランチ
memoを送ると、GitHub がremote:の行で、プルリクエストを作るための URL を返してきました。ブラウザでリポジトリを開くと、同じ案内が Compare & pull request のボタンになって出ます。$ git push -u origin memo remote: remote: Create a pull request for 'memo' on GitHub by visiting: remote: https://github.com/you/memo-app/pull/new/memo remote: To https://github.com/you/memo-app.git * [new branch] memo -> memo branch 'memo' set up to track 'origin/memo'.手元に貼ってある、GitHub 側の付箋の写しの一覧です。GitHub の画面の ブランチの切り替え(main ▼) を開くと出る一覧と、同じ付箋を指しています。
origin/HEAD -> origin/mainは、既定のブランチがmainだという印です。$ git branch -r origin/HEAD -> origin/main origin/main origin/memoorigin/mainから親を辿れるコミットは3つです。GitHub の画面で main を選んだときに出る 3 Commits は、この数です。$ git log --oneline origin/main e5c0a62 (origin/main, origin/HEAD, main) パンを追加 8b41d07 卵を追加 3f2a9c1 牛乳を追加memoから辿ると5つになります。親を辿るとmainのコミットも含まれるので、GitHub の画面で memo を選ぶと 5 Commits と出ます。$ git log --oneline origin/memo 6a1f3c8 (HEAD -> memo, origin/memo) 卵のメモを追加 4d7b2e9 メモを追加 e5c0a62 (origin/main, origin/HEAD, main) パンを追加 8b41d07 卵を追加 3f2a9c1 牛乳を追加いま乗っている
memoの先頭のコミットには、notes.txtとtodo.txtがあります。GitHub の Code タブで memo を選んだときに並ぶファイルと同じです。$ ls notes.txt todo.txtmainに乗り換えて、作業ツリーをmainの先頭のコミットの中身にします。$ git switch main Switched to branch 'main' Your branch is up to date with 'origin/main'.mainの先頭にはtodo.txtしかありません。リポジトリを開いたときの Code タブは、既定のブランチmainのこの中身を見せています。$ ls todo.txtmemoに戻ります。notes.txtはmemoにしか無いので、リポジトリを開いただけでは見えません。これをmainに入れてほしいと頼むのが、プルリクエストです。$ git switch memo Switched to branch 'memo' Your branch is up to date with 'origin/memo'.
notes.txt は GitHub に届いているのに、リポジトリを開いただけでは見えません。Code タブが既定のブランチ main を見せているからです。「届いたはずのファイルが GitHub に無い」と感じたら、まず main ▼ がどのブランチになっているかを見てください。
2. push -u のあとに出る「Compare & pull request」
1 のシーンの最初の git push -u origin memo では、ターミナルに remote: で始まる行が出ていました。この行は Git ではなく、GitHub が書いて送り返してきた案内です。
remote: Create a pull request for 'memo' on GitHub by visiting:
remote: https://github.com/you/memo-app/pull/new/memo
「memo のプルリクエストを作るなら、この URL へ」という意味です。ブラウザでリポジトリを開くと、同じ案内が「memo had recent pushes」という帯と、Compare & pull request のボタンになって出ます。どちらも、「付箋 memo が新しく届いたので、main に取り込む依頼を出しますか」という誘いです。押さなければ何も起きません。帯はしばらくすると消えますが、Pull requests タブの New pull request からいつでも同じ画面に行けます。
3. プルリクエスト — 「このブランチを、あのブランチにマージしてほしい」
Compare & pull request を押すと、プルリクエストを作る画面が開きます。上の方に、こう並んでいます。
base: main ← compare: memo
これがプルリクエストの中身のすべてです。compare(memo)を、base(main)にマージしてほしいという依頼で、矢印の向きは「memo の変更が main に流れ込む」方向です。タイトルと説明を書いて Create pull request を押すと、依頼が GitHub に登録されて #1 のような番号が付きます。
ここで大事なのは、プルリクエストは Git のコマンドではなく、GitHub の機能だということです。git のどのコマンドにも pull request はありません(名前の似た git pull は、2-3 で見た fetch と取り込みのコマンドで、まったく別物です)。プルリクエストを作っても、GitHub 側のグラフにはコミットも付箋も増えません。増えるのは「依頼」と、それについての会話の記録だけです。
プルリクエストの画面には、タブがいくつか並びます。
| タブ | 見せているもの | 手元で近いもの |
|---|---|---|
| Conversation | 依頼の説明・コメント・レビューのやりとり | (Git には無い。GitHub だけの記録) |
| Commits | memo にあって main に無いコミット | git log --oneline main..memo |
| Files changed | マージしたら main がどう変わるかの差分 | git diff main...memo |
Files changed は、main と memo の差分です。正確には「main と memo が分かれた地点から、memo の先頭までの差分」で、memo の側で何を変えたかだけが並びます。プルリクエストを出したあとに memo へコミットを足して push すると、同じプルリクエストの Commits と Files changed に自動で加わります。依頼の対象は「付箋 memo」なので、付箋が進めば依頼の中身も進むわけです。
4. Merge pull request を押すと — GitHub 側だけが変わる
依頼を受けた人(一人で開発しているなら自分)が Merge pull request を押すと、GitHub が GitHub 側のグラフの中でマージをします。既定の方式(Create a merge commit)では、次の2つが起きます。
- 親が2つのマージコミットを1つ作る。1つ目の親は main の先頭、2つ目の親は memo の先頭で、メッセージは
Merge pull request #1 from you/memoになる - GitHub 側の付箋 main を、そのマージコミットへ進める
手元のパソコンには、何も届きません。マージは GitHub の中で起きたことで、手元の main も、写しの origin/main も、押す前のコミットを指したままです。2-3 で「もう1台の PC から push された」場面を見ましたが、それと同じことが GitHub の画面から起きた、と考えると分かりやすくなります。
プルリクエストをマージしたあと、手元を追いつかせる
プルリクエストを出した直後の状態です。GitHub 側も手元も、
memoはmainより2つ先に進んでいます。$ git log --oneline --all 6a1f3c8 (HEAD -> memo, origin/memo) 卵のメモを追加 4d7b2e9 メモを追加 e5c0a62 (origin/main, origin/HEAD, main) パンを追加 8b41d07 卵を追加 3f2a9c1 牛乳を追加GitHub の画面で Merge pull request を押しました。GitHub 側に親が2つのマージコミット
b7e40d2ができて、GitHub 側のmainがそこへ進みます。ターミナルには何も出ません。手元のグラフは何も変わっていません。マージは GitHub の中で起きたことで、手元の
origin/mainはまだ古い写しのままです。$ git log --oneline --all 6a1f3c8 (HEAD -> memo, origin/memo) 卵のメモを追加 4d7b2e9 メモを追加 e5c0a62 (origin/main, origin/HEAD, main) パンを追加 8b41d07 卵を追加 3f2a9c1 牛乳を追加git statusもup to dateと答えます。比べている相手は最後に写したorigin/memoで、GitHub に問い合わせてはいないからです。$ git status On branch memo Your branch is up to date with 'origin/memo'. nothing to commit, working tree cleangit fetchで写しを取り直すと、origin/mainがe5c0a62からb7e40d2へ進みました。手元のmainはまだ動きません。$ git fetch From https://github.com/you/memo-app e5c0a62..b7e40d2 main -> origin/mainマージコミットが手元のグラフにも出ました。
origin/HEADは、GitHub 側の既定のブランチ(ここではmain)を指す写しです。$ git log --oneline --all b7e40d2 (origin/main, origin/HEAD) Merge pull request #1 from you/memo 6a1f3c8 (HEAD -> memo, origin/memo) 卵のメモを追加 4d7b2e9 メモを追加 e5c0a62 (main) パンを追加 8b41d07 卵を追加 3f2a9c1 牛乳を追加mainに乗り換えるとbehind 'origin/main' by 3 commitsと出ます。マージコミットとmemoの2つのコミット、合わせて3つ遅れています。$ git switch main Switched to branch 'main' Your branch is behind 'origin/main' by 3 commits, and can be fast-forwarded. (use "git pull" to update your local branch)手元の
mainの付箋をb7e40d2まで進めます(Fast-forward)。notes.txtがmainにも入りました。$ git pull --ff-only Updating e5c0a62..b7e40d2 Fast-forward notes.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 notes.txt手元の
mainの先頭が、GitHub で作られたマージコミットになりました。GitHub 側のmainと手元のmainが、同じコミットを指しています。残っているmemoの片づけは、次の節で扱います。$ git log --oneline -3 b7e40d2 (HEAD -> main, origin/main, origin/HEAD) Merge pull request #1 from you/memo 6a1f3c8 (origin/memo, memo) 卵のメモを追加 4d7b2e9 メモを追加
マージのあとに手元でやることは、2-3 の手順そのままです。fetch で写しを取り直し、main に乗り換えて git pull --ff-only で付箋を進める。手元の main は GitHub 側の main の後ろにまっすぐ並んでいるので、枝分かれは起きず、Fast-forward(付箋をそのまま前へずらすだけ)で追いつきます。
もう1つ気づいてほしいのは、この場面では GitHub 側の main がプルリクエストを出したあとに1つも進んでいなかったのに、マージコミットが作られたことです。手元で同じ形のマージをすると、Git は付箋をずらすだけで済ませ(Fast-forward)、マージコミットを作りません。GitHub の既定の方式は、いつでもマージコミットを作るようになっています。「いつ、どのプルリクエストを取り込んだか」がグラフに残るようにするためです。手元のマージがいつ Fast-forward になり、いつマージコミットになるかは、第3部の merge の回で扱います。
マージの方式はボタンの横で選べる
Merge pull request のボタンの横の ▼ を開くと、マージの方式を選べます。どれを選べるかはリポジトリの設定で決まり、この回で扱ったのは既定の1つ目だけです。
| 方式 | GitHub 側のグラフで起きること | memo の元のコミット |
|---|---|---|
| Create a merge commit | 親が2つのマージコミットを作り、main を進める(この回の動き) | main から辿れる |
| Squash and merge | memo の変更を1つにまとめた新しいコミットを作り、main を進める(親は1つ) | main からは辿れない |
| Rebase and merge | memo のコミットを main の先頭の上に作り直して並べる(ID が変わる) | main からは辿れない |
Squash と Rebase のときは、中身は同じでも ID の違うコミットが main に入ります。memo の元のコミットは main から辿れないので、手元の memo を git branch -d で消そうとすると、Git に「まだ取り込まれていない」と判断されて止まることがあります。どちらも第3部の rebase の回の内容とつながっているので、そこで改めて見ます。
5. Delete branch — GitHub 側の付箋を剥がすだけ
マージが終わると、プルリクエストの画面に Delete branch のボタンが出ます。押すと消えるのは、GitHub 側の付箋 memo だけです。memo のコミットは、マージコミットの2つ目の親として main から辿れるので、1つも消えません。グラフから付箋が1枚なくなるだけです。消した付箋は、同じ画面の Restore branch で貼り直せます。
手元はここでも何も変わりません。memo という名前は、3か所に別々に貼ってあるからです。
| 付箋 | Delete branch を押すと | 消すには |
|---|---|---|
GitHub 側の memo | 消える | (このボタンで消えた) |
手元の写し origin/memo | 残る | git fetch --prune(GitHub 側に無くなった付箋の写しを剥がす) |
手元の memo | 残る | git branch -d memo(取り込み済みのときだけ消える) |
ふつうの git fetch は、GitHub 側で消えた付箋の写しを残したままにします。写しを片づけるのが git fetch --prune(-p とも書く。prune は「刈り込む」)です。4 のシーンの続きで、Delete branch を押してから3か所の memo を片づけるまでを見ます。
Delete branch のあと — fetch --prune で写しを片づける
プルリクエストをマージして、手元の
mainも追いついたあとの状態です。手元のmemoは、上流のorigin/memoを追跡したままです。$ git branch -vv * main b7e40d2 [origin/main] Merge pull request #1 from you/memo memo 6a1f3c8 [origin/memo] 卵のメモを追加GitHub の画面で Delete branch を押しました。GitHub 側の付箋
memoが剥がれます。コミットはマージコミットの親としてmainから辿れるので、1つも消えません。git fetchを打っても、ここでは何も出ません。GitHub 側で消えた付箋の写しorigin/memoは、手元に残ったままです。$ git fetch手元の
memoとremotes/origin/memoが残っています。Delete branch で消えたのは、GitHub 側の付箋だけです。$ git branch -a * main memo remotes/origin/HEAD -> origin/main remotes/origin/main remotes/origin/memo--prune(刈り込む)を付けると、GitHub 側に無くなった付箋の写しを剥がします。[deleted]の行が、origin/memoを剥がした印です。$ git fetch --prune From https://github.com/you/memo-app - [deleted] (none) -> origin/memo手元の
memoの上流が[origin/memo: gone]になりました。追跡していた写しが無くなった、という意味です。$ git branch -vv * main b7e40d2 [origin/main] Merge pull request #1 from you/memo memo 6a1f3c8 [origin/memo: gone] 卵のメモを追加-dは、まだ取り込まれていないコミットを持つブランチなら止まります。memoのコミットはmainから辿れるので、剥がれたのは付箋だけです。$ git branch -d memo Deleted branch memo (was 6a1f3c8).3か所に貼ってあった
memoが、すべて片づきました。手元に残っているのはmainと、その写しだけです。$ git branch -a * main remotes/origin/HEAD -> origin/main remotes/origin/main
写しが剥がれたあとの git branch -vv に出た [origin/memo: gone] は、「上流として追跡していた写しが無くなった」という印です。gone と出ているブランチは、GitHub 側ではもう片づいたブランチなので、手元でも消してよい候補になります。古い写しが残っていても害はありませんが、git branch -a の一覧が長くなっていきます。
6. Claude Code と gh pr create
Claude Code に「プルリクエストを作って」と頼むと、gh pr create というコマンドを打つことがあります。gh は GitHub CLI(GitHub の画面の操作をターミナルから行うための、GitHub 製の道具)で、git とは別のプログラムです。流れはだいたい次のとおりです。
git switch -c ブランチ名で作業用ブランチを作り、コミットを積むgit push -u origin ブランチ名で GitHub に送る(2-2 の内容)gh pr create --title "…" --body "…"で、そのブランチを main にマージする依頼を出す
3つ目は、ブラウザで Compare & pull request を押してタイトルを書くのと同じことです。GitHub にお願いを出しているだけで、手元のグラフも GitHub 側のグラフも変わりません。ただし、作ったプルリクエストはリポジトリを見られる人全員から見えます。公開リポジトリなら、世界中から見えます。
同じ gh でも、gh pr merge は Merge pull request のボタンを押すのと同じで、GitHub 側の main を進めます。--squash や --rebase を付けると方式が変わり、--delete-branch を付けると、GitHub 側と手元の両方のブランチを消します。gh pr view・gh pr list・gh pr diff は見るだけのコマンドです。
Windows のノート PC と Mac の2台で作業しているなら、片方でプルリクエストをマージしたあと、もう片方では手元の main が古いままです。作業を始める前に git fetch -q と git pull --ff-only を打つ習慣(2-3 で見たもの)が、ここでも効きます。
7. Claude Code の許可画面で見かけたら
この回で見たコマンドを、「何が変わるか・何が消えうるか」で並べるとこうなります。
| コマンド | 何が起きるか | 消えうるもの |
|---|---|---|
git fetch / git fetch -q | 手元の写し(origin/main など)を GitHub 側に合わせて貼り直す。手元のブランチと作業ツリーは動かない | なし |
git fetch --prune / git fetch -p | 上に加えて、GitHub 側で消えた付箋の写し(origin/memo など)を剥がす。手元のブランチは消えない | なし |
git pull --ff-only | 手元のブランチの付箋を、写しの位置までまっすぐ進める。枝分かれしていれば止まる | なし(作業ツリーの書きかけが上書きされるなら止まる) |
gh pr view / gh pr list / gh pr diff | GitHub のプルリクエストを見るだけ | なし |
gh pr create | GitHub にプルリクエスト(マージの依頼)を出す。手元も GitHub 側のグラフも変わらない | なし(ただし、リポジトリを見られる人全員から見える) |
git branch -d ブランチ名 | 手元の付箋を剥がす。まだ取り込まれていないコミットがあれば止まる | なし |
gh pr merge | GitHub 側でマージして、GitHub 側の main を進める | 注意 取り消すには、打ち消すコミットを足す(GitHub の Revert ボタンなど)後始末が要る |
gh pr merge --delete-branch | マージしたうえで、GitHub 側と手元のブランチを消す | 注意 手元のブランチに、まだ push していないコミットが残っていないかを先に確かめる |
見分け方は、GitHub 側の main が動くかどうかです。gh pr create は依頼を出すだけなので、手元のグラフと同じく GitHub 側のグラフも動きません。gh pr merge は、そのリポジトリを使うすべての人の main を進めます。許可する前に、どのプルリクエストをどの方式でマージするのかを確かめてください。
まとめ
- GitHub のリポジトリの画面は、GitHub 側のグラフを1つのブランチから見たもの。
main ▼は付箋の一覧、ファイルの一覧は先頭のコミットの中身、「N Commits」は親を辿れるコミットの数 - プルリクエストは「compare のブランチを base のブランチにマージしてほしい」という依頼。Git のコマンドではなく GitHub の機能で、作ってもグラフは変わらない
- Merge pull request を押すと、GitHub 側にだけ親が2つのマージコミットができて、GitHub 側の main が進む。手元は
git fetch→git switch main→git pull --ff-onlyで追いつく - Delete branch は GitHub 側の付箋を剥がすだけ。手元の
memoはgit branch -d、写しのorigin/memoはgit fetch --pruneで片づける gh pr createは依頼を出すだけ。gh pr mergeは GitHub 側の main を動かす
第2部では、手元のグラフの上に GitHub 側のグラフをもう1つ置いて、両者の間の行き来を見てきました。clone で GitHub 側のグラフを丸ごと写し(2-1)、push で手元のコミットを GitHub 側へ送り(2-2)、fetch で写しを取り直して pull で手元の付箋を進め(2-3)、プルリクエストで GitHub 側のブランチ同士をつなぐ(2-4)。どの操作も、どちらのグラフの、どの付箋が動くかを見れば読めます。
ここまでは、付箋がまっすぐ前に進めるときだけを扱ってきました。2台で別々にコミットして枝分かれしたとき、pull --ff-only は止まります。第3部では、枝分かれした歴史を1つにつなぐ git merge と、歴史を作り直して並べ替える git rebase を、同じグラフで1コマンドずつ見ていきます。