commitlint 不生效的主因是 commit-msg 钩子未触发:需执行 npx husky install、npx husky add .husky/commit-msg 命令,并确保文件可执行;vscode 提交面板可触发钩子,但依赖 husky 正确安装与权限;commitlint 默认仅校验 header,body/footer 需显式配置规则;模板中注释、空行、空格等格式错误会导致 header 解析失败。

commitlint 不生效,90% 是因为 commit-msg 钩子根本没触发——它和 VSCode 提交面板无关,只认 git 命令行流程是否走通。
commit-msg 钩子没装或不可执行,commitlint 就是摆设
你配了 commitlint.config.js、装了依赖、写了规则,但提交照样通过?先别调配置,检查钩子本身是否就位:
-
npx husky install必须执行,否则.husky/目录压根不会创建 -
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'必须手动运行,不能只靠 husky 初始化自动加 - 检查
.husky/commit-msg文件是否存在,且权限为可执行(chmod +x .husky/commit-msg);Windows 用户用 Git Bash 时极易漏这步 - 运行
git commit --allow-empty -m "test"测试:如果没报subject may not be empty类错误,说明钩子根本没跑
VSCode 提交面板能触发 commit-msg,但有个前提
VSCode 源代码管理视图里的提交框,底层调的是 git commit 命令,所以只要钩子存在且可执行,它就会触发。但要注意几个实际断点:
- 如果你在 VSCode 里用了第三方插件(比如 Git Graph 或 Git Tree)直接调
git commit,得确认它没绕过 shell 环境——某些插件会跳过钩子 - 终端里用
git commit -m "xxx"也能触发,但此时$1是临时文件路径,commitlint --edit依赖该路径读取内容;如果手动 -m 提交,commitlint实际校验的是 header 行,body 和 footer 不参与默认规则 - 别指望 VSCode 的“提交模板”(
.gitmessage)能替代校验——模板只是预填充,填错照样能过,commitlint才是守门员
commitlint 默认只校验 header,body/footer 要显式启用规则
很多人写完 feat(auth): add login validation 还加了一大段 body 和 footer,结果依然不报错——因为 commitlint 默认规则集(如 @commitlint/config-conventional)只强制要求 header 格式,body 和 footer 完全可选且无格式约束。
- 若需校验 body 是否为空,加规则:
body-min-length: [2, 'always', 10] - 若要求 footer 包含
closes #xxx,需自定义规则,例如用footer-pattern匹配正则/^closes #\d+$/ - 注意
header-max-length默认是 72,不是 50;如果你团队要求第一行 ≤50 字符,得显式覆盖:header-max-length: [2, 'always', 50] - 所有规则都写在
commitlint.config.js的rules字段下,改完要重新触发一次提交才能验证
模板和校验联动时,最容易忽略的格式细节
你按规范写了 .gitmessage,也启用了 commitlint,但每次提交还是被拒——大概率是模板里多写了空行或注释,破坏了 header 解析。
-
commitlint只解析第一行(header),它必须严格匹配type(scope): description格式;模板里任何前置 # 注释、空行、缩进都会让整行失效 - 模板中不要写
# type: feat这类引导行,那会被当成注释丢弃;header 行必须是纯文本、顶格、无 # - scope 括号不能有空格:
feat( user-auth )会失败,必须是feat(user-auth) - description 开头不能是空格或句号,也不能以问号结尾(除非你关掉
subject-full-stop规则)
真正卡住人的从来不是规则多难写,而是钩子没通电、header 多了个空格、或者以为模板能代替校验——这些地方一错,整个链路就静默失效。











