Git運用 レッスン2
コミットの作法
意味のある単位でコミットを分割し、読み手に伝わるコミットメッセージを書く作法を学ぶ
意味のある単位でコミットする(Atomic Commit)
1つのコミットには、1つの論理的な変更だけを 含めるようにします。これを「アトミックなコミット」と呼びます。 複数の目的が混ざったコミットは、後から特定の変更だけを取り消したり、 原因を特定したりする作業を難しくします。
避けたいコミット
「ログイン機能を追加 + 無関係なタイポ修正 + フォーマッターの一括適用」を 1つのコミットにまとめてしまう
望ましいコミット
「ログイン機能を追加」「タイポを修正」「フォーマッターを適用」を それぞれ独立したコミットに分ける
ポイント
コミットを分けておくと、git bisectで バグ混入コミットを特定しやすくなり、git revertで 特定の変更だけをピンポイントに取り消せるようになります。
良いコミットメッセージの構造
コミットメッセージは、将来の自分やチームメンバーが履歴を読んだときに、 「何を・なぜ変更したか」が伝わるように書きます。 多くのチームでConventional Commitsに似た接頭辞(prefix)を使う運用が採用されています。
<type>: <要約(何をしたか、命令形で簡潔に)>
<本文(任意・なぜその変更が必要だったかの背景)>
<フッター(任意・関連Issue番号など)>
# 例:
feat: 注文履歴のページネーションを追加
一覧表示が1000件を超えると読み込みが遅くなっていたため、
20件ずつのページネーションに変更した。
Closes #482feat: 新機能fix: バグ修正refactor: リファクタリングdocs: ドキュメントtest: テスト追加・修正chore: 雑務・設定変更コミットメッセージのアンチパターン
避けたい例
修正- 何を?wip- 作業中の内容が不明fix bug- どのバグ?
言い換えた例
fix: カート合計金額が税込で計算されない問題を修正feat: 検索結果のページネーションを追加refactor: UserRepositoryをインターフェースベースに変更
インタラクティブrebaseでコミットを整理する
作業中は「wip」「typo修正」のような細かいコミットを積み重ねてしまうこともあります。 プルリクエストとして提出する前に、git rebase -iで コミットを整理し、意味のある単位にまとめ直すことができます。
# 直近5コミットをインタラクティブrebaseで整理する
git rebase -i HEAD~5
# エディタが開き、各コミットに対して操作を選べる
pick a1b2c3d feat: ログインフォームを追加
squash e4f5g6h wip
squash h7i8j9k typo修正
pick k0l1m2n test: ログインフォームのテストを追加
# squash を指定したコミットは直前のコミットに統合されるポイント
rebaseによる履歴の書き換えは、まだ他の人と共有していない自分専用のブランチで 行うのが原則です。すでにpushして他の人が使っている履歴を書き換えると、 チームメンバーの作業と食い違いが生じます。
ポイント
- • 1コミットには1つの論理的な変更だけを含める(Atomic Commit)
- • コミットメッセージは「何を・なぜ」変更したかが伝わるように書く
- • type接頭辞(feat/fix/refactor等)を使うとコミットの種類が一目で分かる
- • プルリクエスト提出前にインタラクティブrebaseでコミットを整理できる
- • 履歴の書き換え(rebase)は、まだ共有していない自分専用のブランチで行う
確認クイズ
1 / 3アトミックなコミットの利点として正しいものはどれか?