commit-msg hook chạy sau khi developer viết commit message — có thể reject nếu message không hợp lệ.
Setup:
npm install --save-dev @commitlint/cli @commitlint/config-conventionalcommitlint.config.js:
module.exports = {
extends: ["@commitlint/config-conventional"],
rules: {
"type-enum": [2, "always", [
"feat", "fix", "docs", "style", "refactor",
"test", "chore", "perf", "ci", "build", "revert", "wip"
]],
"subject-max-length": [1, "always", 100], // warn, not error
"body-max-line-length": [0], // disable
}
};.husky/commit-msg:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no -- commitlint --edit $1Cho phép WIP commits (không block nhưng vẫn có format):
- Thêm "wip" vào type-enum
- wip: payment refactor halfway → pass
Bypass khi thực sự cần (emergency/merge commit):
git commit --no-verify -m "emergency fix"
# --no-verify bỏ qua TẤT CẢ client-side hooksLưu ý: commitlint enforce trên client — developer vẫn có thể bypass bằng --no-verify.
Server-side enforcement cần CI check (dùng commitlint trong GitHub Actions trên PR title).
commit-msg hook runs after the developer writes the commit message — it can reject the message if it does not follow the format.
Setup:
npm install --save-dev @commitlint/cli @commitlint/config-conventionalcommitlint.config.js:
module.exports = {
extends: ["@commitlint/config-conventional"],
rules: {
"type-enum": [2, "always", [
"feat", "fix", "docs", "style", "refactor",
"test", "chore", "perf", "ci", "build", "revert", "wip"
]],
"subject-max-length": [1, "always", 100], // warn, not error
"body-max-line-length": [0], // disable
}
};.husky/commit-msg:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no -- commitlint --edit $1Allow WIP commits (not blocked but still formatted):
- Add "wip" to type-enum
- wip: payment refactor halfway → passes
Bypass when truly needed (emergency/merge commit):
git commit --no-verify -m "emergency fix"
# --no-verify skips ALL client-side hooksNote: commitlint enforces on the client — developers can still bypass with --no-verify.
Server-side enforcement requires CI checks (use commitlint in GitHub Actions to validate PR titles).