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

Bash下Git pre-hook正则校验提交信息失效问题及调试咨询

问题根因
  • 核心bug来自正则里的((.|\n)*)?段:这是无限制贪婪匹配规则,会优先吞掉后续所有字符,加$做结尾锚定时,正则引擎回溯过程无法准确定位到footer段的起始位置,直接导致合法提交匹配失败;去掉$时,只要字符串开头符合规则就会判定匹配成功,自然会把footer后带多余内容的非法提交误判为通过。
  • 脚本存在语法兼容问题:shebang写的是#!/bin/sh,但[[ ]]是Bash独有的语法,在POSIX sh环境下运行会直接报错。
  • 正则细节不符合规范:没有匹配冒号和subject之间的必填空格,也没有匹配段落之间要求的空行,和你定义的提交格式规则不一致。
修正方案

替换正则和脚本头即可,修正后的完整校验脚本:

#!/bin/bash

# 适配git hook场景可替换为 msg=$(cat "$1") 读取提交信息文件
msg="" # 填入待校验的提交信息
# 正则规则拆解:
# ^(test|feat) 匹配开头的必填type,需新增类型直接在括号内追加即可
# (\([^)]+\))? 匹配可选的括号内描述,用[^)]+避免贪婪匹配跨括号
# :  匹配冒号+后面的必填空格
# (.+) 匹配必填subject
# \n\n 匹配subject和后续内容之间的空行
# ((.|\n)*?\n\n)? 非贪婪匹配可选body段,直到遇到footer前的空行
# (Closes #[^ ]+ \([^)]+\)) 匹配必填footer,明确终止符避免贪婪吞内容
# (\n\nBREAKING CHANGE: (.|\n)*)?$ 匹配可选BREAKING CHANGE段,锚定字符串结尾
regExp='^(test|feat)(\([^)]+\))?: (.+)\n\n((.|\n)*?\n\n)?(Closes #[^ ]+ \([^)]+\))(\n\nBREAKING CHANGE: (.|\n)*)?$'

if [[ $msg =~ $regExp ]];
then
    echo "cool"
else
    echo "NOT cool"
    exit 1
fi

无body(subject写完空两行直接接footer)、带BREAKING CHANGE的合法提交都可以正常通过校验;缺footer、footer后带无关内容的提交会被拦截。

正则调试方法

Bash原生提供了匹配结果数组,不需要额外工具就能定位正则问题:

  1. 正则匹配成功后,内置数组${BASH_REMATCH[0]}存储的是整个正则匹配到的完整字符串,打印这个值和原始提交信息做长度、内容对比,如果长度比原始信息短,说明存在未被匹配的内容。
  2. 数组下标从1开始,依次对应正则里每个括号分组匹配到的内容,可以循环打印整个数组,检查每个分组的匹配结果是否符合预期:
if [[ $msg =~ $regExp ]]; then
    echo "完整匹配内容长度: ${#BASH_REMATCH[0]}, 原始内容长度: ${#msg}"
    for i in "${!BASH_REMATCH[@]}"; do
        echo "分组$i匹配结果: ${BASH_REMATCH[$i]}"
    done
fi
  1. 如果匹配失败,可以把正则拆成多个小段,从开头逐段拼接测试:比如先只匹配type和subject,匹配通过后再加body匹配规则,再加footer规则,一步步定位哪段规则存在逻辑问题。
  2. 测试时给msg变量赋值不同场景的样例,覆盖无body、有BREAKING CHANGE、footer后加多余内容、缺footer等情况,逐个验证规则有效性。

内容的提问来源于stack exchange,提问作者Eduardo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 23:51:35