本文目录导读:

要实现Git钩子脚本检查季度里程碑,可以按以下思路编写一个prepare-commit-msg或commit-msg钩子,以下是一个完整的示例脚本:
创建钩子脚本
在 .git/hooks/ 目录下创建 commit-msg 文件:
#!/bin/bash
# 获取提交信息文件路径
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
SHA1=$3
# 读取提交信息
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
# 季度里程碑检查函数
check_quarter_milestone() {
local commit_msg="$1"
# 季度正则匹配模式
# 支持格式:Q1 2024, Q2-2024, 2024-Q3, 2024Q4
local quarter_pattern='(Q[1-4][-\s]?[0-9]{4}|[0-9]{4}[-\s]?Q[1-4])'
if [[ $commit_msg =~ $quarter_pattern ]]; then
return 0 # 包含季度里程碑
else
return 1 # 不包含
fi
}
# 获取当前季度
get_current_quarter() {
local month=$(date +%m)
local year=$(date +%Y)
if [ "$month" -ge 1 ] && [ "$month" -le 3 ]; then
echo "Q1 $year"
elif [ "$month" -ge 4 ] && [ "$month" -le 6 ]; then
echo "Q2 $year"
elif [ "$month" -ge 7 ] && [ "$month" -le 9 ]; then
echo "Q3 $year"
elif [ "$month" -ge 10 ] && [ "$month" -le 12 ]; then
echo "Q4 $year"
fi
}
# 验证季度格式是否正确
validate_quarter_format() {
local commit_msg="$1"
# 严格模式:要求格式为 Q1 2024 或 2024-Q1
local strict_pattern='^(.*\s)?(Q[1-4][-\s][0-9]{4}|[0-9]{4}[-\s]Q[1-4])(\s.*)?$'
if [[ $commit_msg =~ $strict_pattern ]]; then
# 提取匹配的季度字符串
local matched_quarter="${BASH_REMATCH[2]}"
# 验证季度是否有效(1-4)
local quarter_num=$(echo "$matched_quarter" | grep -oP '[1-4]')
local year=$(echo "$matched_quarter" | grep -oP '[0-9]{4}')
if [ "$quarter_num" -ge 1 ] && [ "$quarter_num" -le 4 ]; then
return 0 # 格式有效
fi
fi
return 1 # 格式无效
}
# 主检查逻辑
main() {
# 获取当前季度(用于建议信息)
local current_quarter=$(get_current_quarter)
# 检查提交信息是否包含季度里程碑
if check_quarter_milestone "$COMMIT_MSG"; then
# 验证格式是否正确
if validate_quarter_format "$COMMIT_MSG"; then
echo "✓ 季度里程碑格式正确"
exit 0
else
echo "✗ 季度里程碑格式不正确"
echo " 支持格式示例: Q1 2024, 2024-Q1, Q2-2024"
echo " 当前季度: $current_quarter"
exit 1
fi
else
# 检查是否是合并提交或修复提交(可跳过验证)
if [ "$COMMIT_SOURCE" = "merge" ] || [[ "$COMMIT_MSG" =~ ^(fixup!|squash!) ]]; then
exit 0
fi
echo "✗ 提交信息中未包含季度里程碑"
echo " 建议格式: [Q1 2024] 功能描述"
echo " 当前季度: $current_quarter"
# 交互式提示(可选)
echo ""
echo "是否需要添加季度里程碑? [y/N]"
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
echo "请输入季度里程碑 ( $current_quarter):"
read -r quarter_input
echo "[$quarter_input] $COMMIT_MSG" > "$COMMIT_MSG_FILE"
echo "✓ 已添加季度里程碑"
fi
exit 1 # 强制要求添加
# exit 0 # 如果只是警告不强制
fi
}
main
高级版本(带更多功能)
#!/bin/bash
# .git/hooks/commit-msg 高级版本
COMMIT_MSG_FILE=$1
# 配置
MIN_QUARTER_YEAR=2020 # 最小允许的年份
MAX_QUARTER_YEAR=2030 # 最大允许的年份
STRICT_MODE=true # 严格模式:强制要求季度里程碑
ALLOW_SKIP_PATTERN="^(docs|chore|test):" # 允许跳过的提交类型
# 解析季度信息
parse_quarter_info() {
local commit_msg="$1"
local quarter_info=""
# 尝试匹配不同格式
if [[ $commit_msg =~ (Q[1-4])[-\s]?([0-9]{4}) ]]; then
quarter_info="${BASH_REMATCH[1]} ${BASH_REMATCH[2]}"
elif [[ $commit_msg =~ ([0-9]{4})[-\s]?(Q[1-4]) ]]; then
quarter_info="${BASH_REMATCH[2]} ${BASH_REMATCH[1]}"
fi
echo "$quarter_info"
}
# 检查季度是否合理
is_quarter_reasonable() {
local quarter=$1
local year=$2
# 检查年份范围
if [ "$year" -lt "$MIN_QUARTER_YEAR" ] || [ "$year" -gt "$MAX_QUARTER_YEAR" ]; then
return 1
fi
# 检查季度编号
if [ "$quarter" -lt 1 ] || [ "$quarter" -gt 4 ]; then
return 1
fi
# 可选:检查是否超出当前时间太多
local current_year=$(date +%Y)
local current_quarter=$(( ($(date +%m) - 1) / 3 + 1 ))
# 允许前后各一个季度
local quarter_diff=$(( (year - current_year) * 4 + (quarter - current_quarter) ))
if [ "$quarter_diff" -lt -1 ] || [ "$quarter_diff" -gt 1 ]; then
return 2 # 超出合理范围但允许
fi
return 0
}
# 主逻辑
main() {
local commit_msg=$(cat "$COMMIT_MSG_FILE")
local quarter_info=$(parse_quarter_info "$commit_msg")
if [ -z "$quarter_info" ]; then
# 检查是否跳过
if [[ $commit_msg =~ $ALLOW_SKIP_PATTERN ]]; then
echo "ℹ 跳过类型提交,不强制检查季度里程碑"
exit 0
fi
echo "⚠ 提交信息缺少季度里程碑"
echo " 建议格式: [Q1 2024] 提交描述"
echo " 或者使用 git commit -m 'Q1 2024: 描述'"
if [ "$STRICT_MODE" = true ]; then
exit 1
fi
else
local quarter=$(echo "$quarter_info" | cut -d' ' -f1 | sed 's/Q//')
local year=$(echo "$quarter_info" | cut -d' ' -f2)
echo "ℹ 检测到季度里程碑: $quarter_info"
if ! is_quarter_reasonable "$quarter" "$year"; then
echo "⚠ 警告: 季度 $quarter_info 超出合理范围"
echo " 当前季度: $(get_current_quarter)"
# 非致命错误
fi
# 验证格式一致性
if [[ $commit_msg =~ ^\[Q[1-4]\ [0-9]{4}\] ]] || \
[[ $commit_msg =~ ^Q[1-4]\ [0-9]{4}: ]]; then
echo "✓ 季度里程碑格式正确"
else
echo "⚠ 建议使用标准格式: [Q2 2024] 描述"
fi
fi
}
# 辅助函数
get_current_quarter() {
local month=$(date +%m)
local year=$(date +%Y)
echo "Q$(( (month - 1) / 3 + 1 )) $year"
}
main
安装和使用
# 进入项目目录 cd your-project # 创建钩子文件 cat > .git/hooks/commit-msg << 'EOF' # 把上面脚本内容粘贴到这里 EOF # 设置执行权限 chmod +x .git/hooks/commit-msg # 测试 git commit -m "Q1 2024: 完成功能开发" # 应该通过 git commit -m "修复bug" # 应该被拒绝
自定义配置
你还可以在项目根目录创建 .git-quarter-config 配置文件:
# .git-quarter-config
ENABLED=true
STRICT_MODE=false
MIN_YEAR=2022
MAX_YEAR=2025
ALLOWED_PATTERNS=['Q\d{4}', '\d{4}Q[1-4]']
然后在钩子脚本中读取配置:
if [ -f ".git-quarter-config" ]; then
source .git-quarter-config
fi
这个脚本会根据配置灵活地检查季度里程碑,既支持强制模式也支持警告模式。