ガイド公開日
GitHub の Issue とプルリクエストを、確認の場として使う

Codex 集中講座の第8回。1人で開発していてもプルリクエストを通す理由と、Issue に何を書くか、レビューで見る場所、マージの3つの方式の選び方を扱います
前回で、変更を手元で管理できるようになりました。ここからは、その変更を他人が見られる場所に出します。
「他人」には自分も含まれます。依頼を出したときの自分と、翌日に差分を読む自分は、知っていることが違います。頭の中にあった前提は、一晩で消えます。書かれていないことは、明日の自分にも伝わらない。プルリクエストは、その前提を文字にして残すための場所です。
Issue は、依頼文の置き場所になる
Issue は、やることを1件ずつ立てておく場所です。バグの報告にも、機能の要望にも、作業のメモにも使えます。
Codex と組むときに効くのは、Issue に書いた文章が、そのまま依頼文として使えることです。第6回で整理した3つ、文脈と制約と完了の条件は、そのまま Issue の書き方としても成立します。
## 何が起きているか
日付の表示が西暦のみで、和暦を求める利用者から問い合わせが3件。
## 制約
既存の呼び出し側は変えない。第2引数で切り替える。
## 完了の条件
tests/unit/date.test.ts にテストが追加され、npm test が通る。
この Issue を書いた時点で、依頼文は書き終わっています。あとは Codex に渡すだけです。
Issue を書く手間は、依頼文を書く手間と重なります。二重の作業にはなりません。
プルリクエストは、止まる場所として効く
プルリクエストは、あるブランチの変更を別のブランチへ取り込む提案です。提案なので、出しただけでは反映されません。
1人で開発していても出す理由は、この「出しただけでは反映されない」ところにあります。手元で git merge を打てば一瞬で終わる作業を、わざわざ一度止める。止まっている間に、差分を読み、検査の結果を見て、説明を書きます。
BenriWorks では、ブログのリポジトリで作業用のブランチから既定のブランチへ1回、既定のブランチから本番用の main へもう1回、合計2回のプルリクエストを通しています。2回目は内容を見直すためではなく、いつ本番に出すかを自分で決めるためです。書いた直後に反射的に公開しないための仕掛けとして働いています。
プルリクエストに書くこと
説明欄に書くのは3つです。
何を変えたか。差分を読めば分かりますが、要約が先にあると読む速さが変わります。
なぜ変えたか。差分からは絶対に読み取れない情報です。関連する Issue の番号を書いておけば、そちらに詳しく書いた文章が残ります。
どう確かめたか。テストを追加したのか、手で動かしたのか、確認していないのか。確認していないなら、確認していないと書いてください。あとで問題が出たときに、どこを見ればよいかが決まります。
Codex に説明の下書きを書かせることもできますが、「なぜ」と「どう確かめたか」は人が書くほうが確実です。前者は依頼した人しか知らず、後者は事実の記録だからです。
レビューで見る場所
差分の読み方は第3回で決めました。範囲、消えた行、増えた行、検査の結果の順です。プルリクエストの画面では、これに2つ足します。
ひとつは、変更されたファイルの一覧に依頼していないファイルが混ざっていないかです。GitHub の画面はファイル単位で折りたためるので、まず一覧だけを見ます。
もうひとつは、自動の検査が通っているかです。検査を仕込む方法は第13回で扱いますが、仕込んであれば、この画面に結果が並びます。落ちているものがある状態でマージしないことだけ決めておけば、それだけで事故は減ります。
気になる行にはコメントを残せます。1人で開発していても使ってください。「ここは後で直す」と書いておくと、次に読むときに自分への申し送りになります。
マージの3つの方式
取り込むときの方式は3つあります。
merge は、作業ブランチの全部のコミットをそのまま残し、合流したことを示すコミットを1つ足します。作業の過程が履歴に残ります。
squash は、作業ブランチの変更を1つのコミットにまとめて取り込みます。履歴が短くなり、1つのプルリクエストが1つのコミットに対応します。
rebase は、作業ブランチのコミットを取り込み先の先頭に並べ直します。履歴が一直線になりますが、コミットの識別子が変わるため、すでに共有しているブランチでは扱いに注意が要ります。
選び方の目安は、1つのプルリクエストが1つの意味を持っているかどうかです。持っているなら squash が読みやすくなります。持っていない、つまり複数の意味が混ざっているなら、方式を選ぶ前にプルリクエストを分けるほうが先です。
壊れたときに戻す場所
プルリクエストをマージしたあとで問題に気づくことはあります。
squash でマージしていれば、打ち消すのはコミット1つです。第7回の git revert に、そのコミットを指定します。プルリクエストの画面から取り消しの操作を始めることもできます。
ここでも効いているのは、1つのまとまりが1つの意味を持っているという形です。意味が混ざっていると、打ち消したときに、残したかった変更まで一緒に消えます。粒度の話は、コミットからプルリクエストまで同じ理屈で続いています。
保護の設定を1つだけ入れる
GitHub には、ブランチへ直接反映することを禁じる設定があります。
全部を設定する必要はありません。最初に入れるとよいのは、本番用のブランチへは、プルリクエストを経由しないと反映できないという1つだけです。手が滑って直接反映してしまう事故を防げます。
自動の検査を仕込んだあとは、検査が通ったものだけ反映できる設定を足します。これは第13回で、検査そのものと一緒に扱います。
次の回
ここまでで、AIが書いたものを人が確かめて反映するまでの道筋ができました。ただ、確かめる作業は毎回発生します。
第9回からの4回は、この確認を減らすための仕組みです。毎回同じ指摘をしなくて済むように、リポジトリの側に規約を置きます。まず AGENTS.md から始めます。
参照した情報
- GitHub Docs のプルリクエスト、レビュー、ブランチ保護に関する各ページ(docs.github.com)
- BenriWorks のブログリポジトリで実際に運用している2段階のリリース手順
よくある質問
- 1人で開発しているのにプルリクエストは必要ですか
- 必要になります。1人であっても、依頼したときの自分と差分を読むときの自分は別の状態にあります。プルリクエストは、変更のまとまりに説明をつけて一度止める仕掛けで、止まる場所があること自体に効き目があります。自動の検査を差し込む場所としても、ここが一番使えます。
- Issue は書かなくてもよいのではないですか
- 小さな修正なら省いて構いません。ただ、Codex に任せる作業では、依頼の内容をどこかに残しておくと後で効きます。Issue に書いた文章は、そのまま依頼文として使えますし、あとで「なぜこの変更をしたか」を探す手がかりにもなります。
- マージの方式はどれを選べばよいですか
- 1つのプルリクエストが1つの意味を持つ形に作れているなら squash が読みやすく、履歴が短くなります。作業の過程そのものを残したいときは merge です。rebase は履歴が一直線になりますが、コミットの識別子が変わるため、共有済みのブランチでは扱いに注意が要ります。



