本文目录导读:

要实现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
这个脚本会根据配置灵活地检查季度里程碑,既支持强制模式也支持警告模式。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播