Bash编写Git服务端钩子校验硬编码提交信息格式失效求助
Git服务端提交信息格式校验钩子实现方案
需求说明
- 基于Bash编写Git服务端钩子,对所有待推送的提交执行commit message格式校验
- 只要待推送提交中存在任意一条不符合指定格式,直接拒绝本次推送
- 合规提交信息必须按顺序包含5个必填字段:
Project Name:、Jira ID:、Testing Status:、Employee Name:、Office:
场景示例
不合规提交(需拦截)
执行git log -1查看提交信息仅为Updated java file.,无指定必填字段,需拦截推送:
$ git log -1 commit 98yad93c64d06f8cd49a8905b2b28f7509c87aef (HEAD -> master) Author: Admin <admin@company.com> Date: Mon Jun 20 16:33:00 2022 +0530 Updated java file.
合规提交(需放行)
提交信息按顺序包含全部5个指定字段,允许推送:
$ git log -1 commit c4d4a5c1d83ca1327c1b7e57f60eabe161d467b3 (HEAD -> master) Author: Admin <admin@company.com> Date: Mon Jun 20 16:33:00 2022 +0530 1. Project Name: Java App 2. Jira ID: 12345 3. Testing Status: Completed 4. Employee Name: Robby Nithin 5. Office: Norway
原有脚本失效原因
原脚本存在3个致命逻辑错误,导致校验完全不生效:
- 完全没有读取待推送的提交内容:Git
pre-receive钩子通过标准输入传入待更新的提交区间,原脚本既没有读取该输入,也没有提取任何提交的message,反而去读取服务器上固定的/opt/template文件,校验对象和本次推送完全无关 - 正则语法错误:
grep -E多关键字匹配需要用|分隔规则,原脚本用逗号分隔关键字,匹配逻辑完全不符合预期 - 无顺序校验逻辑:原逻辑只要匹配到任意一个关键字就判定通过,既不校验字段是否齐全,也不校验字段顺序,不符合规则要求
可用修复脚本
将以下脚本部署到Git服务端仓库的hooks/pre-receive路径,赋予可执行权限即可生效:
#!/bin/bash # 定义顺序匹配正则:兼容字段前带数字序号、前后空格的写法,要求5个字段按顺序出现 REGEX_PATTERN='^[[:space:]]*[0-9]*\.?[[:space:]]*Project Name:.*\ ^[[:space:]]*[0-9]*\.?[[:space:]]*Jira ID:.*\ ^[[:space:]]*[0-9]*\.?[[:space:]]*Testing Status:.*\ ^[[:space:]]*[0-9]*\.?[[:space:]]*Employee Name:.*\ ^[[:space:]]*[0-9]*\.?[[:space:]]*Office:.*' ZERO_COMMIT="0000000000000000000000000000000000000000" RETURN_CODE=0 # 读取pre-receive传入的所有待更新引用 while read oldrev newrev refname; do # 跳过分支删除场景 if [ "$newrev" = "$ZERO_COMMIT" ]; then continue fi # 确定本次需要校验的提交范围 if [ "$oldrev" = "$ZERO_COMMIT" ]; then # 新建分支场景:校验新分支上所有不在现有分支内的提交 COMMIT_RANGE=$(git rev-list "$newrev" --not --all) else # 正常推送场景:校验旧提交到新提交之间的所有增量提交 COMMIT_RANGE=$(git rev-list "$oldrev".."$newrev") fi # 逐提交校验格式 for commit in $COMMIT_RANGE; do # 提取当前提交的完整提交信息 COMMIT_MSG=$(git log -1 --pretty=format:%B "$commit") # 跨行匹配正则校验 if ! echo "$COMMIT_MSG" | grep -qPz "$REGEX_PATTERN"; then echo "ERROR: 提交 $commit 信息格式不符合规范,推送被拒绝" echo "提交信息必须按顺序包含以下5个字段:" echo "1. Project Name: <项目名称>" echo "2. Jira ID: <Jira工单编号>" echo "3. Testing Status: <测试状态>" echo "4. Employee Name: <提交人姓名>" echo "5. Office: <办公地点>" echo "----------------------------------------" echo "当前不合规提交的信息为:" echo "$COMMIT_MSG" RETURN_CODE=1 fi done done exit $RETURN_CODE
部署注意事项
- 脚本文件名必须为
pre-receive,存放在目标仓库的hooks目录下 - 必须给脚本添加可执行权限,执行命令:
chmod +x hooks/pre-receive - 脚本自动兼容分支新建、正常推送、分支删除三种常见场景,不会误拦截分支删除操作
- 正则规则兼容示例中的数字序号前缀写法,字段前后允许存在空格,适配日常提交习惯
内容的提问来源于stack exchange,提问作者user4948798
相关产品推荐
相关产品推荐

