Stop Using Conventional Commits: Why Scope, Not Type, Should Lead Git Messages
The article argues that Conventional Commits is a harmful anti‑pattern because it puts the optional type before the far more important scope, promises automatic changelogs and version bumps that don’t work, and proposes the proven scoped‑commit format used by Linux, Git, Go and others.
1. Priority Reversed: type before scope
Conventional Commits defines the format <type>[optional scope]: <description> with types such as fix, feat, chore, docs, refactor. The scope is optional and placed after the type. The author claims scope is about 100× more important than type, yet the spec treats it as secondary.
Who cares about scope? All roles.
Three typical scenarios illustrate this:
Scenario 1 – Contributor pulling latest code : After git log the developer wants to know which module changed, e.g.
fix(auth): 修复登录超时
feat(payment): 新增支付宝回调
refactor(core): 重构配置加载versus a format that puts the scope first:
auth: 修复登录超时
payment: 新增支付宝回调
core: 重构配置加载The latter lets the developer locate the relevant module in 0.5 seconds.
Scenario 2 – Debugging a production bug : When a payment‑related error occurs, the engineer needs scope = payment. Whether the commit is a fix, feat or refactor is irrelevant; the bug could stem from any type.
Scenario 3 – Incident response : An API error spike is traced to a commit affecting auth. The crucial information is scope = auth; the type is meaningless.
In all three cases, type adds noise while scope provides the actionable insight.
2. type is often redundant
Example from the Angular project:
fix(compiler): prevent namespaced SVG <style> elements from being strippedRemoving the type yields:
compiler: prevent namespaced SVG <style> elements from being strippedThe description already conveys that this is a bug fix. Another commit:
refactor(core): Update webmcp support to use document.modelContextmixes a refactor with new functionality and a bug fix, making the type ambiguous and wasting subject‑line characters.
3. Empty promises: automatic changelog
Conventional Commits promises tools like git‑cliff or conventional‑changelog can generate a changelog automatically. The author points out that the commit log audience (developers) cares about module‑level changes, while the changelog audience (users) cares about business‑level features. These are different granularities. For a feature such as “user avatar upload”, eight commits may be needed: <code>feat(upload): 添加文件上传接口 fix(upload): 修复大文件超时 refactor(avatar): 抽离头像裁剪逻辑 feat(avatar): 前端接入头像上传 test(avatar): 补充单元测试 docs(avatar): 更新 API 文档 fix(avatar): 修复 iOS Safari 兼容问题 feat(settings): 设置页面增加头像入口</code> A user only needs to know that the avatar upload feature was added, not the intermediate bug fixes and refactors. Mixing these granularities in a changelog confuses users. 4. Automatic version bump issues You may forget a breaking change and label it as feat , causing an incorrect minor version bump. You may think a change is breaking, label it as such, then later add a fix that restores compatibility, resulting in an unnecessary major bump. Reverting a breaking change still leaves the tool detecting the original breaking change, so the major version is still increased. Manual version decisions are cheap; automating them adds risk without benefit. 5. Using type to trigger builds is unsafe Some pipelines run security scans only for feat and fix , skipping docs . If a commit like <code>docs: fix typos</code> actually modifies the auth module and introduces a backdoor, the automated check is bypassed, shifting all responsibility to manual review. 6. Better alternative: Scoped Commits Projects such as Linux, Git, Go, NixOS and Node.js use a scope‑prefixed format where the scope appears first and the type is omitted: Linux : i2c: virtio: mark device ready before registering Git : gitlab-ci: update macOS image Go : net/http/cookiejar: add godoc links NixOS : xwayland: 24.1.11 -> 24.1.12 Node.js : stream: fast-path stateless transform flush In these projects the scope is defined by the subsystem, package path, or service name, providing three advantages: High information density – every character conveys useful data. Correct priority – the first thing you see is the affected module. Friendly to all roles – contributors, debuggers and incident responders can locate relevant changes instantly. 7. Why Conventional Commits persists Two main reasons: Brand war : It has a catchy name, an official website and tooling (commitlint, semantic‑release), giving it marketing momentum. AI propagation : Code‑generation assistants such as GitHub Copilot and Claude Code are trained on large codebases that use Conventional Commits, so they automatically suggest this format, spreading the anti‑pattern further. Conclusion The core flaw of Conventional Commits is misplacing focus – the optional type is placed first while the truly critical scope is optional and hidden. The proven scoped‑commit format, used by major projects like Linux, Git and Go, puts scope first and drops the type, delivering concise, module‑centric commit messages that serve developers, debuggers and responders alike.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Code Mala Tang
Read source code together, write articles together, and enjoy spicy hot pot together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
