Conventional Commits: Why a Focus on Type Over Scope is a Technical Anti-Pattern
Conventional Commits はコミットメッセージを構造化するために広く採用されている標準ですが、根本的に間違ったメタデータを優先しています。コミットタイプ(例: fix、feat)をスコープ(変更されたコード領域)より先に置くことで、実際にコミットログを読む人々、すなわち貢献者、デバッガ、インシデント対応者にとって最も重要な情報を提供できていません。
The Failure of Type-First Prioritization
Conventional Commits はタイプを必須、スコープを任意とする形式を義務付けています。これは技術的な失敗です。なぜなら、変更の対象であるスコープこそがコードベースをナビゲートする上で最も重要な情報だからです。
Why Scope Outweighs Type
多くの技術的ステークホルダーにとって、触れられたコード領域は変更のカテゴリよりも価値があります。
- Contributors: 特定のコードベース領域での変更を特定し、プロジェクトの慣性を理解したり、潜在的なマージコンフリクトを見つけたりする必要があります。
- Debuggers: 発生したバグに関連するコンポーネントの変更を検索します。変更のタイプは関係なく、バグはどのコミットタイプからでも導入され得ます。
- Incident Responders: 本番障害時にログをスキャンし、エラー急増と相関する特定サブシステム(例:
auth)の変更を探します。
The Redundancy of Commit Types
コミットタイプはしばしば冗長です。なぜなら、よく書かれた説明は通常タイプを暗示するからです。例えば、fix(compiler): prevent namespaced SVG <style> elements from being stripped というコミットは、fix: プレフィックスがなくてもバグ修正であることが明らかです。さらに、Conventional Commits の硬直したカテゴリは制約が強く、1 つの変更が同時にリファクタ、バグ修正、機能追加であることが多々あります。
The Illusion of Automated Benefits
Conventional Commits は実際のソフトウェアエンジニアリングシナリオでしばしば失敗する自動化の利点を約束します。
Automated Changelogs
自動生成されたチェンジログは 2 つの異なる受け手を混同します。開発者(コミットログを読んでコードベースの変遷を把握する人)とエンドユーザー(機能的なビジネス変更を理解するためにチェンジログを読む人)です。1 つの機能は複数のコミットを必要とすることが多く、これらのコミットの生リストをユーザーに提示するのは最適ではありません。さらに、リバートは問題を引き起こします。リバートされた変更はエンドユーザーには通常見えないべきですが、開発者の履歴には重要です。
Automated Semantic Versioning (SemVer)
コミットタイプでバージョン上げをトリガーする(例: feat! でメジャー版)ことは、以下の要因で信頼性が低いです。
- Reverts: 直ちにリバートされた破壊的変更でも、自動ツールはメジャー版上げを引き起こす可能性があります。
- Accidental Breakages: 微妙な破壊的変更がコミット時に判別できず、誤ったマイナー/パッチ版上げになることがあります。
- Retroactive Fixes: 後続のコミットでリリース前に破壊的変更が解消されても、ツールは最初の破壊的コミットを見続けます。
Automated Build and Publish Triggers
コミットタイプに基づいてセキュリティチェックやビルドをトリガーする(例: docs: でチェックをスキップ)ことはセキュリティリスクです。悪意ある攻撃者が docs: とラベル付けしながら認証サブシステムに脆弱性を導入すれば、自動ツールを回避できます。
A Proven Alternative: Scope-Prefixed Commits
Linux カーネル、Git、Go、FreeBSD など、最も成功したオープンソースプロジェクトの多くは Conventional Commits 標準を拒否し、スコーププレフィックス方式のメッセージを採用しています。これらのプロジェクトではスコープが主要な識別子であり、タイプは暗黙的か省略されています。
| Project | Format | Example |
|---|---|---|
| Linux | subsystem: description |
i2c: virtio: mark device ready before registering the adapter |
| Go | package: description |
net/http/cookiejar: add godoc links |
| Git | area: description |
gitlab-ci: update macOS image |
| FreeBSD | prefix: description |
linuxulator: Return EINVAL for invalid inotify flags |
Community Perspectives and Counterpoints
Conventional Commits への批判は鋭いものの、コミュニティの議論は標準が存続するいくつかの理由を浮き彫りにしています。
- Enforcement and Quality Control: 一部のメンテナは、未熟な開発者による「ひどい」コミットメッセージを防ぐ唯一の手段として、プリコミットフックでスキーマを強制すべきだと主張します。
- Continuous Delivery (CD): 小規模プロジェクトや積極的な CD パイプラインを持つプロジェクトでは、コミットタイプに基づいて自動的にタグ付け・リリースできることが大きな運用上の利点です。
- The "Good Enough" Standard: JSON がコメントを持たないにも関わらず広く採用された例になぞらえて、最適ではなくても定義された構造が全くないよりはマシだと主張する開発者もいます。
最終的に議論の焦点は、コミットメッセージが自動化のための機械可読トリガーであるべきか、人間が読むためのアーキテクチャ変遷の記録であるべきかにあります。大規模で長寿命なプロジェクトの証拠は、スコープと人間の可読性を優先し、タイプに依存した自動化を抑える方が持続可能なアプローチであることを示しています。