Conventional Commits là convention format: type(scope): description. Types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert.
Tại sao không chỉ "agree": agreement không có enforcement = mọi người quên hoặc bỏ qua khi deadline gần. Sau 3 tháng, git log trở thành "fix stuff", "update", "wip", "asdfgh".
Setup commitlint + husky:
npm install --save-dev @commitlint/cli @commitlint/config-conventional husky
# commitlint.config.js:
module.exports = { extends: ["@commitlint/config-conventional"] }
# .husky/commit-msg:
npx --no -- commitlint --edit $1Lợi ích thực tế:
- semantic-release tự động bump version và generate CHANGELOG từ commits
- git log --oneline readable: thấy ngay đây là feature hay fix
- PR title auto-generate từ commit message
- Breaking changes: feat!: hoặc BREAKING CHANGE: footer tự động trigger major version bump
Lưu ý: đừng reject commit của mọi người khi scope sai — chỉ enforce type và description format, để scope optional.
Conventional Commits is a message format: type(scope): description. Types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert.
Why not just agree: agreement without enforcement means people forget or skip it under deadline pressure. After 3 months, git log becomes "fix stuff", "update", "wip", "asdfgh".
Setup commitlint + husky:
npm install --save-dev @commitlint/cli @commitlint/config-conventional husky
# commitlint.config.js:
module.exports = { extends: ["@commitlint/config-conventional"] }
# .husky/commit-msg:
npx --no -- commitlint --edit $1Real benefits:
- semantic-release auto-bumps version and generates CHANGELOG from commits
- git log --oneline is readable: immediately see if it is a feature or fix
- PR titles auto-generated from commit messages
- Breaking changes: feat!: or BREAKING CHANGE: footer automatically triggers a major version bump
Note: do not reject commits over a wrong scope — only enforce type and description format, keep scope optional.