commit-msg钩子应拦截三类高风险提交:新增非白名单许可证、擅自修改LICENSE文件、硬编码许可证片段;需匹配敏感关键词且无#LEGAL-XXX、!legal或chore(legal)等合规标识,否则阻断并提示补全。

直接在 commit-msg 钩子中校验许可证合规性,核心不是“检测许可证文本”,而是**拦截引入新许可证或修改现有许可证的提交行为**——前提是这些行为未通过预设的合规流程(如法务审批、LICENSE 文件统一更新)。正则本身不解析法律条款,但能精准识别高风险模式。
明确阻断目标:哪些提交该被拦住?
commit-msg 钩子应聚焦拦截以下三类高风险提交信息:
-
新增非白名单许可证声明:提交信息含
add license、introduce MIT、include Apache-2.0等字眼,且未关联已批准的工单号(如#LEGAL-42) -
擅自修改 LICENSE 文件:提交信息匹配
^.*LICENSE.*$或^.*license.*$,但未带!legal标识(表示已走法务流程) -
在代码中硬编码许可证片段:提交信息含
copy header、add copyright notice、inject license text等关键词,且作用域(scope)未限定为legal或compliance
正则规则设计:轻量但精准
在 .git/hooks/commit-msg 中嵌入如下逻辑(Shell 示例):
GInstall OneClick — 一键安装 GitHub 项目:规划、克隆、安装 Node 依赖、运行开发脚本。适用于想要获取 GitHubNode.js 项目的用户。
# 读取提交信息 COMMIT_MSG=$(cat "$1") <h1>定义许可证敏感模式(不区分大小写)</h1><p>if [[ "$COMMIT_MSG" =~ [[:space:]]+(add|include|use|switch|replace|remove)[[:space:]]+(license|mit|apache|gpl|bsd|unlicense|cc0)[[:space:]]<em>($|[^a-zA-Z0-9]) ]] || \ [[ "$COMMIT_MSG" =~ ^[[:space:]]</em>LICENSE[[:space:]]<em> ]] || \ [[ "$COMMIT_MSG" =~ [[:space:]]+(copyright|notice|header)[[:space:]]+(add|inject|embed)[[:space:]]</em> ]]; then</p><h1>检查是否附带合规标识(如法务工单或特殊前缀)</h1><p>if ! [[ "$COMMIT_MSG" =~ #[[:space:]]*[A-Z]+-[0-9]+ ]] && \ ! [[ "$COMMIT_MSG" =~ !legal ]] && \ ! [[ "$COMMIT_MSG" =~ ^(chore|docs)(legal): ]]; then echo "❌ 许可证变更需法务审批:请在提交信息末尾添加 #LEGAL-XXX 工单号,或使用 !legal 标识" echo "✅ 合规示例:chore(legal): update LICENSE file #LEGAL-789" exit 1 fi fi
与现有提交规范协同工作
不要孤立使用许可证校验。它必须叠加在标准语义化提交格式之上:
- 先验证基础格式:
^(feat|fix|chore|docs)(\([^)]+\))?: .+ - 再检查许可证关键词是否出现在
chore或docs类型中,且 scope 为legal、license或空(空 scope 视为高风险) - 对
chore(legal)类提交,额外要求描述中含LICENSE或SPDX字样,避免泛化
配套动作不能少
仅靠钩子不够,需同步落地:
- 在项目根目录放
LICENSE-APPROVALS.md,列出所有已批准许可证及适用场景 - CI 流水线中增加
license-check步骤,扫描LICENSE、NOTICE和源文件头部,与提交信息交叉验证 - 给
chore(legal)提交配置自动标签(如 GitHub Actions),触发法务团队通知

















