You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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个致命逻辑错误,导致校验完全不生效:

  1. 完全没有读取待推送的提交内容:Git pre-receive 钩子通过标准输入传入待更新的提交区间,原脚本既没有读取该输入,也没有提取任何提交的message,反而去读取服务器上固定的/opt/template文件,校验对象和本次推送完全无关
  2. 正则语法错误:grep -E 多关键字匹配需要用|分隔规则,原脚本用逗号分隔关键字,匹配逻辑完全不符合预期
  3. 无顺序校验逻辑:原逻辑只要匹配到任意一个关键字就判定通过,既不校验字段是否齐全,也不校验字段顺序,不符合规则要求

可用修复脚本

将以下脚本部署到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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 14:48:23