Git钩子脚本如何检查月度任务

wen 实用脚本 1

本文目录导读:

Git钩子脚本如何检查月度任务

  1. 核心逻辑
  2. 示例 1:检查本月是否存在特定文件(如月度报告)
  3. 示例 2:检查本月的Git标签是否存在(如发布标记)
  4. 示例 3:检查外部API或数据库记录(高级)
  5. 重要注意事项
  6. 更完善的方案:结合服务端钩子

我们可以通过Git钩子(Hook) 来检查“月度任务”是否完成,但需要先明确:Git钩子是针对每次提交、推送等操作触发的,无法主动按月轮询,通常的实现思路是:在提交或推送时,检查本月是否满足特定条件(如本月已完成某个任务、生成了月度报告文件等)。

以下是几种常见场景的脚本实现方案:


核心逻辑

pre-commitpre-push 钩子中:

  1. 获取当前日期(年、月)。
  2. 检查是否存在该月的“任务完成标记”(文件、Git标签、数据库记录等)。
  3. 如果未完成,则拒绝提交/推送并给出提示。

示例 1:检查本月是否存在特定文件(如月度报告)

假设团队约定:每月必须在仓库根目录提交一个 report-YYYY-MM.md 文件。

脚本:.git/hooks/pre-commit(需赋予执行权限 chmod +x

#!/bin/bash
# 获取当前年月
year=$(date +%Y)
month=$(date +%m)
expected_file="report-${year}-${month}.md"
# 检查工作区或最新提交中是否存在该文件
# 方法A:检查工作区(未提交的文件也算,适合要求本地生成后再提交)
if [ ! -f "$expected_file" ]; then
    echo "❌ 月度任务未完成:缺少本月报告文件 $expected_file"
    echo "请先生成该文件再提交。"
    exit 1
fi
# 方法B:检查最新提交的HEAD中是否存在(适合已提交过的远程校验)
# if ! git show HEAD:$expected_file > /dev/null 2>&1; then
#     echo "❌ 月度任务未完成:HEAD提交中缺少 $expected_file"
#     exit 1
# fi
echo "✅ 月度文件检查通过"
exit 0

示例 2:检查本月的Git标签是否存在(如发布标记)

场景:每月需要打一个 release-YYYY-MM 标签才能进行代码推送。

脚本:.git/hooks/pre-push

#!/bin/bash
# 获取当前年月
tag_name="release-$(date +%Y-%m)"
# 检查本地或远程是否存在该标签
if ! git tag -l | grep -q "^${tag_name}$"; then
    echo "❌ 月度任务未完成:缺少标签 $tag_name"
    echo "请先创建标签: git tag $tag_name && git push origin $tag_name"
    exit 1
fi
echo "✅ 月度标签检查通过"
exit 0

示例 3:检查外部API或数据库记录(高级)

如果月度任务状态存储在外部的服务器或数据库中,可在钩子中调用API检查。

#!/bin/bash
month=$(date +%Y-%m)
check_url="https://your-task-tracker.com/api/check?user=$(git config user.email)&month=$month"
# 模拟HTTP请求(需要curl)
response=$(curl -s --max-time 5 "$check_url")
if [ "$response" != "completed" ]; then
    echo "❌ 本月任务状态:$response"
    echo "请完成月度任务后再提交。"
    exit 1
fi
exit 0

重要注意事项

  1. 钩子保存在本地.git/hooks/ 目录不会被git推送,需要团队手动部署。

    • 解决办法:将脚本放在仓库的 scripts/hooks/ 目录下,团队成员通过 make setup-hooks 或符号链接同步。
  2. 客户端钩子易绕过:用户可用 --no-verify 跳过 pre-commit 钩子,或通过 git push --no-verify 跳过 pre-push

    更严格的校验需要服务端钩子(如GitHub Actions、GitLab CI、Gitee Webhook)配合。

  3. 时区问题date 命令依赖系统时区,跨时区团队建议统一使用UTC时间。

  4. 性能影响:若钩子调用外部API,需设置超时避免阻塞。


更完善的方案:结合服务端钩子

如果希望强制检查,更可靠的是在服务端(如GitLab的自定义钩子或GitHub的Actions) 进行校验:

GitLab 服务端 pre-receive 钩子示例

#!/bin/bash
# 部署在服务端 hooks/pre-receive
while read oldrev newrev refname; do
    month=$(date +%Y-%m)
    # 检查推送的提交中是否包含月度文件
    if ! git diff-tree --no-commit-id -r "$newrev" --name-only | grep -q "report-${month}.md"; then
        echo "❌ 拒绝推送:缺少本月报告文件 report-${month}.md"
        exit 1
    fi
done
exit 0

需求场景 推荐钩子类型 检查方式
每月需提交固定文件 pre-commit 检查工作区或HEAD中是否存在该月文件
每月需打标签 pre-push 检查是否存在本月的标签
任务状态在外部系统 pre-push 调用外部API
强制团队遵守 服务端钩子/CI 服务端 pre-receive或CI脚本

选择哪种方式取决于你的强制力要求基础设施,对于团队内部规范,客户端钩子 + 文档说明通常足够。

抱歉,评论功能暂时关闭!