概要
- Conventional Commits は多くのプロジェクトで使われているが、本質的な問題点が多い
- 変更の スコープ よりもタイプ(fix, feat等)を優先し、実用性に欠ける
- Changelog自動生成 などのメリットも実際には十分に機能しない
- 成功している多くのプロジェクトは スコープ重視 のコミットメッセージを採用
- より良いコミットメッセージの構造とその理由を提案
Conventional Commitsの問題点
- Conventional Commits は、コミットメッセージにセマンティックな意味を持たせることを目的
- フォーマット例: <type>[optional scope]: <description>
- type (例: fix, feat, chore等)が先頭に来て、 scope は任意
- scope (どの部分を変更したか)が最重要だが、typeが優先されている現状
- scopeが任意であるため、 「主語のない文」 のようなメッセージが生まれやすい
- typeの情報は 冗長 であり、説明文から容易に判断できる場合がほとんど
- typeの選択が難しく、 複数のタイプに該当する変更 では逆に混乱を招く
スコープ重視の重要性
- コントリビューター :自分の興味範囲や作業中の部分に関連する変更を探す際、scopeが最重要
- デバッガー :バグ発生時、どの領域が変更されたか(scope)がバグ特定の鍵
- インシデント対応者 :障害発生時、scopeから原因箇所を特定しやすい
- いずれも type情報はほぼ役に立たず、scopeが本質的に重要
Conventional Commitsの約束と現実
- Changelog自動生成 :
- コミットログとChangelogの 利用者層・目的が異なる
- Changelog:ユーザー向け、機能・ビジネス観点の変化を知りたい
- Commit log:開発者向け、コードベースの変遷を追いたい
- 複雑な機能追加は複数コミットに分かれるため、Changelogには不向き
- revert コミットの扱いも不十分
- セマンティックバージョン自動判定 :
- revertや誤ったtype指定で 誤ったバージョンアップ が発生
- 実際のソフトウェア開発の流れに合わない
- 変更内容の伝達 :
- ChangelogとCommit logの目的・対象が異なるため、両立できていない
- 自動ビルド・公開トリガー :
- タイプ指定に依存した自動化は セキュリティリスク や誤動作の温床
- 実際はgit diff等でscopeを見て処理する方が安全
- 貢献のしやすさ :
- フォーマットは整うが、 実際の貢献のしやすさには寄与しない
実運用上の課題
- プロジェクトごとに type定義が必要 だが、多くはcommitlintのデフォルトを流用
- 企業プロジェクトでは チケット番号 をscopeに入れるケースが多く、scopeの意義が薄れる
スコープ重視型コミットメッセージの推奨
- Linux, FreeBSD, Git, Go, NixOS など著名プロジェクトはscope重視のフォーマットを採用
- 例:
- Linux: サブシステム: 説明 (i2c: virtio: mark device ready before registering the adapter)
- Go: パッケージ: 説明 (net/http/cookiejar: add godoc links)
- NixOS: パッケージ名: 説明 (xwayland: 24.1.11 -> 24.1.12)
- scopeはプロジェクトごとに 自然に決まる (サブシステム名、パッケージパス、マイクロサービス名等)
結論と提案
- Conventional Commitsの利点は幻想的 であり、実際の価値は低い
- しかし普及しているため、AIもこのフォーマットをデフォルトで使いがち
- より良いコミットメッセージ構造 としてscope重視型を推奨
- Changelog生成とコミットログ管理は 分離すべき
- 今後は scopedcommits.com などを通じて、より良いプラクティスの普及を目指す