Part 2 開発の基本動作
第6章 変更をレビューにつなげる
第5章では、手元でアプリを動かし、ログを読み、作業場の状態を記録した。 第6章では、その手元の作業を、チームが読める変更として渡す。
コードを書いたあと、差分だけを見せればレビューできると思ってしまうことがある。 しかし、レビュアーは差分だけで判断しているわけではない。 なぜ変えたのか、何を変えたのか、何を変えていないのか、どう確認したのか、どこを見てほしいのかを合わせて読む。
この章で学ぶのは、Gitコマンドを暗記することではない。 変更を小さくまとめ、履歴に残し、Pull Requestとして説明し、レビューコメントに返す流れである。 変更をレビュー可能な単位へ編集する技術だと考えると、GitとGitHubの操作は一本の線でつながる。
この章でできるようになること
この章のゴールは、Gitを使ったという事実を残すことではない。 自分がどのrepositoryで、どのbranchにいて、何を変更し、どの差分をレビューへ出したのかを説明できるようになることである。
- 作業前に、repository、branch、未commitの変更、remote、直近の履歴を確認できる。
- working tree、staging area、commitを分けて考え、次のcommitに入る差分を自分で読める。
- 一つの目的に絞ったbranchとcommitを作れる。
- PR本文に、背景、変更内容、今回やらないこと、確認方法、影響範囲、レビューしてほしい点を書ける。
- レビューコメントを、修正、質問、別PR、代替案のどれで返すか判断できる。
- conflict markerを見たとき、文字列だけでなく両方の変更意図を読める。
- AIにGitやPR文を手伝わせる場合でも、危険なコマンドと未確認の記述を止められる。
差分は、説明されて初めてレビューできる
題材として、メンター向けの担当受講者一覧を考える。 担当受講者が0件のとき、画面が空白に見えてしまう。 そこで、空状態の案内文を追加したいとする。
この変更は小さく見える。 しかし、レビューで確認すべき点は一つではない。 本当に担当受講者が0件の場合だけなのか。 フィルタ結果が0件の場合とは文言を分けるべきか。 既存の一覧表示に影響していないか。 メンターが次に何をすればよいか分かる表現になっているか。
つまり、レビュー対象はコードの行だけではない。 変更の目的、対象範囲、確認結果、残る判断もレビュー対象である。
第4章で作った change-description.md は、PR本文の背景と変更内容になる。
第5章で作った local-run-log.md は、確認方法と実行結果になる。
第6章では、この二つをGitの履歴とGitHubのレビューへつなげる。
GitとGitHubを分けて考える
Gitは、手元で変更履歴を管理する仕組みである。 GitHubは、その履歴をチームで共有し、Pull Requestやレビューを行う場所である。
| 観点 | Git | GitHub |
|---|---|---|
| 主な役割 | 手元で変更履歴を作る | 変更履歴を共有し、PRやレビューを行う |
| 主に見る場所 | ターミナル、エディタ | ブラウザ、GitHub CLI(gh) |
| よく見る情報 | branch、status、diff、commit、remote | PR URL、PR本文、review comments、merge条件 |
| 相談で伝えること | どのbranchで、どんな差分があり、どのcommitまで進んだか | どのPRで、誰から何を指摘され、何を判断したいか |
この違いを曖昧にすると、いま何をしているのかが分からなくなる。 手元で差分を見る、次のcommitに入れる変更を選ぶ、commitを作る。 これは主にGitの作業である。 branchを共有する、Pull Requestを作る、review commentに返信する、mergeする。 これは主にGitHub上の共同作業である。
もちろん実務では両方を行き来する。
それでも、困ったときはまず切り分ける。
git status や git diff で見る問題なのか。
Pull Requestの本文、レビュー、権限、merge条件で見る問題なのか。
どちら側の話かを分けるだけで、相談しやすくなる。
working tree、staging area、commit
Gitで最初に押さえるべき関係は、working tree、staging area、commitである。
working treeは、いま編集しているファイル群の状態である。 エディタでファイルを変更すると、まずworking treeに変更が現れる。
staging areaは、次のcommitに含める変更を選んで置く場所である。
git add は、変更をいきなり完成させる操作ではない。
次のcommitに入れる候補として選ぶ操作である。
commitは、選んだ変更を履歴に残す単位である。 commitは保存ボタンではない。 あとから読んだ人が、何のために何を変えたのかを追える作業単位である。
この三つを分けると、Gitの操作は落ち着いて見える。 まずworking treeに変更がある。 次に必要な変更だけをstaging areaへ入れる。 最後にcommitとして履歴に残す。
よく使う確認コマンドは、見る場所が違う。
| コマンド | 何を見るか | 読み方 |
|---|---|---|
git status |
working treeとstaging areaの状態 | 変更があるか、stagedか、untrackedかを見る |
git diff |
まだstagingしていない差分 | 編集中の変更をcommitに入れる前に読む |
git add <file> |
指定したファイルの変更をstaging areaへ入れる | 次のcommitに含める候補として選ぶ |
git diff --staged |
次のcommitに入る予定の差分 | commit直前に必ず読む |
git commit -m "..." |
staging areaの内容を履歴に残す | 目的が一つにまとまった単位で残す |
git add は、その時点の変更をstaging areaへ入れる操作である。
git add のあとに同じファイルをさらに編集すると、staging済みの差分と、まだstagingしていない差分が同時に存在することがある。
そのため、commit前には git status と git diff --staged の両方を見る。
作業前にrepositoryの現在地を見る
変更を始める前に、repositoryの現在地を確認する。 repositoryは、Gitが履歴を管理している作業場所である。 第5章のプロジェクトルート確認と同じで、Gitにも現在地確認がある。
最初に見るのは、次の四つである。 必要に応じて、直近の履歴も見る。
- どのディレクトリで作業しているか。
- どのbranchにいるか。
- commitしていない変更があるか。
- remoteはどこを向いているか。
pwd は作業場所を確認する。
git status はGitの現在地を確認する。
git branch --show-current は現在のbranchを確認する。
git remote -v は共有先を確認する。
git log --oneline -5 は直近の履歴を見る。
ここを飛ばすと、違うbranchで作業したり、前の作業の変更を混ぜたり、想定外のremoteへpushしたりしやすくなる。 Gitの事故の多くは、難しいコマンドを知らないことより、現在地を見ずに進めたことから起きる。
現在地確認では、コマンドを実行した事実だけでなく、読んだ結果を短く残す。
## 作業前の状態
- branch: main
- git status: commitしていない変更なし
- remote: origin が想定したGitHub repositoryを向いている
- 最新commit: a1b2c3d Add local run log template
- 気づいたこと: 作業前の状態はcleanなので、新しいbranchを作れる
git status に変更中のファイルが出ているなら、すぐに次へ進まない。
前の作業の続きなのか、今回の作業に必要な変更なのか、消してよい一時ファイルなのかを分ける。
ここを曖昧にしたままbranchやcommitを作ると、関係ない変更がPRに混ざる。
意味が分からないまま実行しないGit操作
Gitには、履歴や作業中のファイルへ大きな影響を与える操作がある。 実務で必要になることはあるが、研修中に意味が分からないまま実行してはいけない。
| コマンド | 何が起き得るか | 困ったときの扱い |
|---|---|---|
git reset --hard |
commitしていない変更が失われることがある | 実行前に、残す変更がないかメンターに確認する |
git clean -fd |
Gitが追跡していないファイルやディレクトリを削除する | 生成物か必要なファイルかを確認してから相談する |
git push --force |
remote上の履歴を書き換えることがある | チームのbranchでは独断で使わない |
git rebase |
commit履歴を並べ替えたり作り直したりする | チームの運用ルールを確認してから使う |
git cherry-pick |
別のcommitを現在のbranchへ取り込む | 取り込む理由と影響範囲を説明できる場合だけ使う |
AIや検索結果がこれらを提案しても、そのまま実行しない。
相談するときは、現在のbranch、git status の結果、実行しようとしている目的、残したい変更を伝える。
branchは、作業の目的を分ける
branchは、本流を直接変えずに作業を進める場所である。 多くのチームでは、main branchに安定した状態を置き、新しい機能や修正は作業用branchで進める。
branch名は、作業の目的が分かる名前にする。
たとえば、担当受講者一覧の空状態を追加するなら feature/progress-empty-state のように書ける。
バグ修正なら fix/submission-filter、文書更新なら docs/update-setup-guide のように、種類と内容が見えるとよい。
branchで大切なのは、名前の美しさではない。 一つのbranchに一つの目的を持たせることである。 空状態の案内文を追加するbranchに、未提出者フィルタの仕様変更や別画面のリファクタリングまで混ぜると、レビューする人は判断しにくくなる。
レビューしやすいbranchは、戻しやすいbranchでもある。 変更の目的が小さければ、問題が起きたときに影響範囲を説明しやすい。
作業branchを作る前にも git status を見る。
未commitの変更がある状態でbranchを作ると、その変更を持ったまま新しいbranchへ移ることがある。
それが意図した変更なら問題ないが、前の作業の残りなら混入の原因になる。
この章の題材なら、作業開始は次のように記録できる。
git switch -c feature/progress-empty-state
branch名は、あとからPR一覧で見たときに目的が伝わる程度でよい。 短さよりも、作業対象と変更内容が読めることを優先する。
commit前に差分を読む
変更したら、commitする前に差分を読む。
git diff は、まだcommitしていない変更の中身を見るためのコマンドである。
追加された行、削除された行、変わったファイルを確認できる。
差分を読む目的は、間違い探しだけではない。 自分がこれからチームに渡す変更を、自分の言葉で説明できるかを確認するためである。 AIが作った変更でも同じである。 AIが編集したから分からない、ではレビューへ渡せない。
git add した後は、git diff --staged を見る。
これは、次のcommitに入る予定の差分である。
working tree全体の差分ではなく、commitに含めると選んだ差分だけを見る。
git add . は便利だが、意図しないファイルまでstagingすることがある。
初学者のうちは、まず git status で変更ファイルを見て、必要なファイルを明示するほうが安全である。
git status
git diff
git add src/server.js
git diff --staged
複数ファイルを変更した場合は、ファイルごとに「今回の目的に必要か」を見る。
メモ、ログ、一時ファイル、.env、スクリーンショット、依存関係のlock fileなどは、混ざりやすい。
必要なファイルなら理由を説明し、不要ならstagingしない。
commit前チェックでは、少なくとも次を見る。
- 変更したファイルは意図どおりか。
- 関係ない変更が混ざっていないか。
- staging areaに入れた差分は、次のcommitに必要なものだけか。
- APIキー、トークン、個人情報、内部情報が含まれていないか。
- ローカルで最低限の確認をしたか。
- commit messageは変更意図を表しているか。
commit messageは、未来の読者への短い説明である。
fix や update だけでは、何を直したのかが分かりにくい。
Add empty state copy for progress list のように、対象と変更内容が読める形にすると、履歴を追いやすい。
ただし、commit messageは説明の入口であって、証拠ではない。
本当にその変更だけが入っているかは、git diff --staged で確認する。
Pull Requestは、完成報告ではなく変更提案である
Pull Requestは、branch上の変更をチームに見せ、レビューしてもらう単位である。 略してPRと呼ぶ。 PRは、完成しましたと報告するだけの場所ではない。 この変更を取り込んでよいか判断してもらうための提案である。
良いPR本文には、少なくとも次がある。
- 背景。
- 変更内容。
- 今回やらないこと。
- 確認方法。
- 影響範囲とリスク。
- レビューしてほしい点。
- AIを使った場合の検証。
悪いPR本文は、たとえば次のようなものだ。
「進捗一覧を直しました。」
これでは、なぜ直したのか、何を変えたのか、どう確認したのか、レビュアーがどこを見ればよいのかが分からない。
良いPR本文は、次のように書ける。
背景: 担当受講者がまだいないメンターが進捗一覧を開くと、空白画面に見えてしまいます。
変更内容: 担当受講者が0件の場合に、進捗一覧へ案内文を表示しました。 担当受講者がいる場合の一覧表示は変更していません。
今回やらないこと: 未提出者フィルタの仕様変更と自動アラートは、このPRに含めません。
確認方法: 担当受講者が0件の状態で進捗一覧を開き、案内文が表示されることを確認しました。 担当受講者がいる状態では、既存の一覧表示が変わらないことを確認しました。
影響範囲、リスク: メンター向け進捗一覧の空状態表示だけを対象にしています。 担当受講者がいる場合の一覧表示、未提出者フィルタ、自動通知は変更していません。
レビューしてほしい点: 案内文が初回リリースの表現として自然かを見てほしいです。 既存の一覧表示に不要な影響がないかも確認してほしいです。
AIを使った場合の検証: AIにはPR本文の抜け漏れ確認だけを依頼しました。 差分、実行結果、確認方法は自分で確認し、実行していない確認は書いていません。
このPR本文なら、レビュアーは差分を読む前に目的を理解できる。 差分のどこを重点的に見ればよいかも分かる。
PRは、差分、本文、会話の三つで成り立つ。 差分だけが正しくても、本文に確認方法がなければ判断しにくい。 本文が丁寧でも、差分に関係ない変更が混ざっていればレビューしにくい。 会話で決まった判断が残っていなければ、あとからなぜその形にしたのか追いにくい。
セルフレビューで、依頼前に自分の差分を読む
レビューを依頼する前に、自分でPR差分を読む。 セルフレビューは、形式的な礼儀ではない。 自分の変更を他の人が読める状態にする最後の確認である。
見る観点は三つから始める。 第一に、変更目的と差分が合っているか。 第二に、関係ない変更や秘密情報が混ざっていないか。 第三に、確認方法と結果が、実際に行った内容になっているか。
権限、データ、ユーザー影響が関わる変更なら、その観点も加える。 支援ステータスや担当受講者一覧のように、メンターや受講者の見え方に関わる変更では、文言、空状態、エラー表示、権限不足時のふるまいまで見る必要がある。
実行していない確認をPR本文に書いてはいけない。 確認できていないことは、未確認として残す。 未確認事項を正直に書くことは、弱さではなく、レビューで判断するための材料である。
レビューコメントには、次の行動で返す
コードレビューは、間違い探しだけではない。 変更を安全に取り込むための共同作業である。 コメントが来たときは、感情的に受け取るのではなく、次の行動へ分ける。
主な返し方は四つである。
- 修正する。
- 質問する。
- 今回は別PRに分ける。
- 代替案を出す。
たとえば、レビュアーから「担当受講者が0件の場合と、フィルタ結果が0件の場合で表示文言を分けたほうがよさそうです」と言われたとする。 この場合、指摘は単なる文言修正ではない。 二つの状態を同じ空状態として扱ってよいのか、という仕様確認である。
返信は、次のように書ける。
「指摘の通り、担当受講者が0件の場合とフィルタ結果が0件の場合は、利用者の次の行動が違うと理解しました。このPRでは担当受講者0件の文言だけを追加し、フィルタ結果0件の文言は別状態として追って対応します。今回は既存のフィルタ挙動を変えないことも確認しました。」
この返信では、指摘の理解、判断、今回の対応範囲、確認結果が分かる。 レビュー返信は、反論でも謝罪文でもない。 変更の判断を共同で残す記録である。
レビュー後の修正は、追加commitとしてPRに加えることが多い。 修正したら、もう一度差分を確認する。 返信では、何を変え、どう確認したかを短く残す。
この章の演習では、次のようにコメントを分けて考える。
| コメント | 判断の例 | 返信に入れること |
|---|---|---|
| 担当受講者0件とフィルタ結果0件の文言を分けたい | 修正する、または仕様確認する | 二つの状態の違い、今回の対応範囲、確認結果 |
| 文言が断定的すぎる | 修正する | 利用者の次の行動が分かる表現にしたこと |
| 未提出者フィルタも同じPRで直したい | 別PRに分ける | 今回のPRの目的、分ける理由、follow-upの扱い |
返信案は、結果だけでなく判断を残す。
コメントBへの返信案:
文言が強く、メンターの次の行動が分かりにくい点を修正しました。
「担当受講者が割り当てられると、ここに進捗が表示されます。」に変更し、担当受講者がいる場合の一覧表示が変わらないことを確認しました。
コメントCへの返信案:
未提出者フィルタの挙動変更は影響範囲が別なので、このPRには含めません。
このPRでは担当受講者0件の空状態だけに絞り、フィルタ結果0件の文言と挙動は別PRで扱うのがよいと考えています。
conflictは、人間の判断が必要というサインである
conflictは、Gitが自動では最終状態を決められない変更がある状態である。 失敗というより、人間の判断が必要というサインである。
たとえば、同じ表示文言に対して二つのbranchが別々の変更を入れたとする。 conflict markerは、次のように見えることがある。
<<<<<<< HEAD
担当受講者が割り当てられると、ここに進捗が表示されます。
=======
条件に一致する受講者はいません。フィルタ条件を変更してください。
>>>>>>> feature/filter-empty-state
markerの意味を、形として覚えておく。
<<<<<<< HEADから=======までが一方の変更である。=======から>>>>>>> ...までがもう一方の変更である。- 通常のmergeでは、
HEADは現在checkoutしているbranch側を指す。 >>>>>>>の後ろには、相手側のbranch名やcommit情報が表示されることがある。
ただし、rebaseなど操作の種類によって見え方が紛らわしくなることがある。 だから、conflictを見たら、markerだけで判断せず、いま何の操作中か、どのbranch同士を合わせようとしているかも確認する。
目的は、markerを消すことだけではない。 上側の変更は、担当受講者が0件の状態を表している。 下側の変更は、フィルタ条件に一致する受講者が0件の状態を表している。 二つは似ているが、利用者の次の行動が違う。
したがって、どちらか一方を機械的に残すのではなく、二つの状態を別々に扱う設計が必要かもしれない。 conflict解消は、文字列を整える作業ではなく、変更意図を読み直す作業である。
conflictを解消するときは、次の順で考える。
- どのファイルでconflictしているかを
git statusで見る。 - markerの上側と下側が、それぞれ何の状態や仕様を表しているかを書く。
- どちらか一方を残すのか、両方を別条件として残すのか、別案にするのかを決める。
- markerを消し、最終的に残すコードや文言だけにする。
- 関連する動作確認をやり直す。
- 判断理由と確認結果を
conflict-and-history-note.mdに残す。
履歴も判断材料になる。
git log --oneline -5 で直近のcommitを見る。
git show <commit-sha> で特定commitの差分を見る。
GitHub上では、PRの会話、review comments、commit listを見る。
履歴を見るときは、何を判断するために見たのかを一緒に残す。
履歴を見る目的は、犯人探しではない。 どの変更が、どの目的で、どの確認を経て入ったのかを知るためである。 たとえば、フィルタ結果0件の文言が別PRで追加されていたなら、今回の空状態文言と混ぜずに、状態を分けて扱う判断につながる。
AIを使うなら、差分を読んだ後に使う
AIは、GitとGitHubの作業でも役に立つ。 差分の要約、commit message案、PR本文の抜け漏れ確認、レビューコメントへの返信案、conflict markerの読み方の説明に使える。
ただし、AIの要約をそのままPRへ貼ってはいけない。 差分を読まずにcommitしてはいけない。 実行していない確認を、AIの提案だからといってPR本文に書いてはいけない。
特に、意味が分からないまま実行してはいけないコマンドがある。
git reset --hard、git clean -fd、git push --force、git rebase、git cherry-pick である。
これらは状況によって必要になることもあるが、研修中に独断で実行する操作ではない。
AIが提案した場合も、そのまま実行せず、メンターに相談する。
AIへ依頼するときは、実際の差分は自分で確認済みであること、秘密情報は含めていないこと、実行していない確認を追加しないでほしいことを明記する。 AIは文章の抜け漏れを見つける補助として使い、採用判断は人が行う。
依頼文は、次のようにできる。
進捗一覧の空状態追加PRについて、PR本文の抜け漏れを確認してください。
差分と実行結果は自分で確認済みです。
実行していないテストや確認を追加しないでください。
秘密情報、実在の個人情報、内部URLは含めていません。
見てほしいこと:
- 背景、変更内容、今回やらないこと、確認方法、影響範囲、レビュー観点が揃っているか
- レビュー担当者が判断しにくい曖昧な表現がないか
- AIが推測で補っている箇所がないか
AIの返答を採用するときは、PR本文にそのまま貼る前に、差分、実行結果、課題README、チームルールと照合する。 AIが「テスト済み」「影響なし」と書いた場合でも、自分が確認していないなら削る。
差分とレビュー準備で確認すること
git-work-log.md、pull-request-note.md、review-response-log.md、conflict-and-history-note.md を作り、変更をレビューへ渡す。
git-work-log.md には、作業repository、作業前のbranch、作業前の状態、remote、最新commit、作業branch、差分確認、stagingしたファイル、commit message、ローカル確認を書く。
pull-request-note.md には、PR URL、背景、変更内容、今回やらないこと、確認方法、影響範囲とリスク、レビューしてほしい点、AIを使った場合の検証を書く。
review-response-log.md には、レビューコメントごとに、修正する、質問する、別PRに分ける、代替案を出す、のどれで返すか、理由、返信案、追加commitを書く。
conflict-and-history-note.md には、conflictで起きていること、上側と下側の変更意図、最終的に残す内容、その理由、履歴から確認したこと、相談する場合に伝えることを書く。
成果物の目的は、Git操作をした証拠を並べることではない。 変更をどの単位で履歴に残し、どう説明し、レビューで何を判断したかを後から読めるようにすることである。
GitとPRで起きやすい誤解
- Gitを、ファイルを保存するだけの道具だと思う。
- 作業前にbranch、status、remoteを確認しない。
- 関係ない変更を同じcommitや同じPRに混ぜる。
git add .の後にgit diff --stagedを見ない。- commit messageを書いたことで、差分確認まで済んだ気になる。
- PR本文に、背景や確認方法を書かない。
- 実行していない確認を、PR本文に書く。
- レビュー返信を「修正しました」だけで終える。
- レビューで決まった判断をPR上に残さない。
- conflict markerを消すことだけに集中し、両方の変更意図を読まない。
- conflict解消後に、関連する動作確認をやり直さない。
- AIが提案した破壊的コマンドを、意味が分からないまま実行する。
変更をレビューにつなげる章で持ち帰ること
第6章で身につけるべきことは、手元の変更をレビュー可能な単位へ変換することである。 Gitでは、working tree、staging area、commitを分けて見る。 branchでは、作業の目的を分ける。 Pull Requestでは、背景、変更内容、確認方法、リスク、レビューしてほしい点を渡す。 レビューコメントには、次の行動と確認結果で返す。
良いGit操作とは、コマンドを速く打つことではない。 未来の自分やチームが、変更の理由、範囲、確認結果を追える状態を作ることである。
Web通信を観察する章へ
次章では、画面操作の裏で起きるHTTP通信を見る。 PR本文に書く確認方法の一部は、ブラウザのNetworkタブやcurlから得られる。 画面で何が起きたかを通信として説明できると、レビューで渡せる証拠が増える。