コミットメッセージの書き方・Conventional Commitsという共通ルール
前記事では、git logやpickaxe検索を使って過去のコミットを探す方法を見ました。ただし、いくら探し方が上手くても、コミットメッセージそのものが手がかりになっていなければ探しようがありません。今回は、探す側ではなく書く側の視点から、コミットメッセージの書き方を整理します。
「何をしたか」はdiffが教えてくれる。書くべきは「なぜ」
コミットメッセージは変更内容を要約すればいいと思うかもしれません。ですが、実際に何のファイルのどの行が変わったかは、コミットのdiffを見れば誰でも分かります。コミットメッセージにわざわざ書く価値があるのは、diffを読んでも分からない「なぜその変更が必要だったのか」という背景です。
# 悪い例: diffを見れば分かることをそのまま書いているだけ git commit -m "nullチェックを追加" # 良い例: なぜ必要だったのかという背景が分かる git commit -m "fix: 未ログイン時にAPIがnullを返す不具合でクラッシュしていたためnullチェックを追加"
建築の設計図の変更履歴に例えると、「何を変えたか」の欄には「壁の位置を10cm移動」とだけ書かれていても、それを見た次の担当者は「なぜ移動したのか」が分からず困ってしまいます。きちんとした変更履歴には、変更理由の欄が必ず併記されています。「配管と干渉することが施工時に判明したため」のような一文があるだけで、次に同じ図面を触る人が同じ失敗を繰り返さずに済みます。コミットメッセージの「なぜ」も、これと同じ役割を果たします。
typeプレフィックスという、チームを越えて通じる共通の型
分かりやすく自由に書けばそれで十分だと思うかもしれませんが、書き手ごとに自由な形式で書いていると、後から機械的に集計したり分類したりすることができません。そこで広く使われているのがConventional Commitsという規約で、コミットメッセージの先頭にfeat:やfix:といったtypeを付けることを定めています。
git commit -m "feat: CSVエクスポート機能を追加" git commit -m "fix: 日付の時差計算が9時間ずれていた不具合を修正" git commit -m "docs: READMEにセットアップ手順を追記" # 後方互換を壊す変更には footer に BREAKING CHANGE を明記する git commit -m "feat: 認証APIのレスポンス形式を変更 BREAKING CHANGE: レスポンスのuser_idフィールドをidに改名した"
Conventional Commitsの仕様では、fixタイプのコミットはセマンティックバージョニングのPATCH(修正版)に、featタイプはMINOR(機能追加版)に、そしてBREAKING CHANGEを含むコミットはタイプに関わらずMAJOR(破壊的変更版)に、それぞれ対応づけて考えるという決まりがあります。typeを揃えておくだけで、リリースノートの自動生成やバージョン番号の判断まで機械的に行えるようになります。
宅配便の伝票に例えると、typeプレフィックスは「われもの注意」「冷蔵」「普通」といった品目コードのようなものです。伝票の中身欄(コミットメッセージ本文)を1件ずつ読まなくても、コードを見ただけで倉庫の担当者は仕分け方を機械的に判断できます。featは「新しく届いた荷物」、fixは「返品交換の荷物」に相当すると考えると、なぜtypeで先に仕分けておくと便利なのかが実感しやすくなります。
よくあるはまりポイント:AIに書かせたメッセージが「なぜ」を素通りする
AIにコミットメッセージの生成を任せれば、面倒な言語化から解放されると思うかもしれません。実際、diffを渡して「コミットメッセージを書いて」とだけ頼むと、AIは変更されたファイルや行を的確に要約したメッセージを一瞬で返してくれます。ですがこの方法では、AIが参照できる情報がdiffの中身に限られているため、どうしても「〜を追加」「〜を修正」というdiffの言い換えに留まりがちで、この記事の1つ目の見出しで扱った「なぜ」の部分が抜け落ちてしまいます。AIにコミットメッセージを頼むときは、diffだけを渡すのではなく、「未ログイン時のクラッシュ対応として」のように変更の背景を一言添えたうえで生成させると、後から読み返しても意味の通るメッセージになります。
- Conventional Commits
- コミットメッセージの先頭にfeat/fixなどのtypeを付けることを定めた広く使われている規約
- feat / fix
- featは新機能追加、fixはバグ修正を表すtype。それぞれセマンティックバージョニングのMINOR/PATCHに対応づけて扱われる
- BREAKING CHANGE
- footerに記載する、後方互換を壊す変更であることを示す注記。typeに関わらずMAJORバージョンアップの根拠として扱われる
コミットメッセージの良し悪しに迷ったら、「半年後に別の担当者がこのコミットだけを見て、変更の意図を理解できるか」を基準に判断しましょう。typeプレフィックスは分類のための型に過ぎず、それだけでは「なぜ」までは伝わらないという点を忘れないようにしてください。
意図の通ったコミットを積み重ねていても、特定の1つだけを別のブランチに移植したい場面が出てきます。続くgit cherry-pickでは、そのための操作を扱います。