本文目录导读:

下面是一个使用 Git 钩子脚本 检查年度目标的思路和示例,核心思路是:在提交或推送时,强制开发者更新或确认与年度目标关联的某个文件(如 annual-goals.md 或 VERSION),如果文件未更新,则拒绝操作。
基本检查逻辑
假设你的项目中有一个文件 ANNUAL_GOALS.md,其中记录年度目标,每次提交或推送前,脚本检查该文件的 Last updated: 时间戳是否为当年。
示例脚本:pre-commit 钩子
保存为 .git/hooks/pre-commit,并赋予执行权限(chmod +x .git/hooks/pre-commit):
#!/bin/sh
# 文件:.git/hooks/pre-commit
# 功能:检查年度目标文件是否已更新到当前年份
GOAL_FILE="ANNUAL_GOALS.md"
CURRENT_YEAR=$(date +%Y)
# 检查文件是否存在
if [ ! -f "$GOAL_FILE" ]; then
echo "错误:找不到年度目标文件 $GOAL_FILE"
echo "请在项目根目录创建该文件并填写年度目标"
exit 1
fi
# 检查文件中是否包含当前年份
if ! grep -q "$CURRENT_YEAR" "$GOAL_FILE"; then
echo "警告:年度目标文件 $GOAL_FILE 中未包含当前年份 $CURRENT_YEAR"
echo "请更新文件,确保其中包含 $CURRENT_YEAR 年度的目标"
exit 1
fi
# 可选:检查文件中是否有 "Last updated:" 且日期在当年
if grep -q "^Last updated:" "$GOAL_FILE" 2>/dev/null; then
LAST_YEAR=$(grep "^Last updated:" "$GOAL_FILE" | sed 's/.*20\([0-9][0-9]\)/20\1/')
if [ "$LAST_YEAR" -lt "$CURRENT_YEAR" ]; then
echo "警告:年度目标最后更新于 $LAST_YEAR,需要更新到 $CURRENT_YEAR"
exit 1
fi
fi
exit 0
工作原理:
- 检查目标文件是否存在
- 检查文件中是否包含当前年份文本
- 如果文件中包含
Last updated: YYYY-MM-DD格式,则验证年份是否 >= 当前年份
更严格的方案:使用 .goal-version 文件
创建一个单独的文件 .goal-version仅为当前年度版本号(如 2024),然后在提交时强制检查:
#!/bin/sh
# pre-commit 钩子
VERSION_FILE=".goal-version"
CURRENT_YEAR=$(date +%Y)
if [ ! -f "$VERSION_FILE" ]; then
echo "错误:缺少 $VERSION_FILE 文件,请创建并写入 $CURRENT_YEAR"
exit 1
fi
VERSION_CONTENT=$(cat "$VERSION_FILE" | tr -d '[:space:]')
if [ "$VERSION_CONTENT" != "$CURRENT_YEAR" ]; then
echo "错误:$VERSION_FILE 内容应为 $CURRENT_YEAR,当前为 $VERSION_CONTENT"
exit 1
fi
exit 0
应对特殊场景
新年份第一次提交
当跨年时,需要更新目标文件,否则所有提交都会被拒绝,建议在团队中约定:
- 每年初由负责人更新年度目标文件
- 更新后作为一个常规提交
允许临时跳过检查
可以增加一个环境变量来跳过检查(如 SKIP_GOAL_CHECK=1):
if [ -n "$SKIP_GOAL_CHECK" ]; then
echo "跳过年度目标检查(已设置 SKIP_GOAL_CHECK)"
exit 0
fi
使用方式:SKIP_GOAL_CHECK=1 git commit -m "紧急修复"
作为 prepare-commit-msg 钩子
可以在提交信息中自动添加年度目标状态,而不是阻止提交:
#!/bin/sh
# prepare-commit-msg 钩子
COMMIT_MSG_FILE=$1
CURRENT_YEAR=$(date +%Y)
if grep -q "$CURRENT_YEAR" "ANNUAL_GOALS.md" 2>/dev/null; then
echo ""
echo "# 年度目标状态:已更新到 $CURRENT_YEAR"
else
echo ""
echo "# 注意:年度目标文件尚未更新!"
fi >> "$COMMIT_MSG_FILE"
团队协作建议
-
将钩子脚本纳入版本控制
可以将脚本放在scripts/git-hooks/目录下,并通过git config core.hooksPath scripts/git-hooks让所有开发者使用相同脚本。 -
配合 CI/CD 使用
在 CI 流水线中也加入类似检查,防止有人绕过本地钩子。 -
编写文档
创建HOOKS_README.md说明检查逻辑和更新方法。 -
考虑使用 git actions 替代
如果团队不是所有人都能设置本地钩子,可以在 GitHub/GitLab 上使用 Action/Hook 检查 PR。
| 方案 | 优点 | 缺点 |
|---|---|---|
| pre-commit 钩子 | 本地强制检查 | 需每台机器配置 |
| prepare-commit-msg 钩子 | 仅提醒,不强制阻断 | 容易被忽略 |
| .goal-version 文件 | 极简检查 | 信息量少 |
| CI/CD 流水线检查 | 集中统一 | 只能在推送时检查 |
最佳实践建议:本地使用 pre-commit 钩子 + 远程 CI 双重检查,确保年度目标及时更新。