如何实现pre-commit钩子升级后自动全仓库重跑对应钩子?
如何在pre-commit钩子升级时自动全量运行目标钩子?
需求背景
我们使用类似Black这类工具的pre-commit钩子时,当钩子升级到行为发生重大变更的版本,理想状态下需要在全仓库所有文件上重跑该钩子,而非仅检查后续修改的文件。同时希望平时保持pre-commit只检查修改文件的正常行为,自动检测钩子升级场景并触发全量运行。
现有思路的问题
- 封装
pre-commit autoupdate:该命令会在所有文件上运行全部钩子,无法仅针对已升级的钩子执行,效率偏低。 - CI中监听pre-commit配置文件变更:无法精准定位要运行的钩子,且无关配置变更也会触发任务,不符合预期。
最优实现方案
1. 本地升级场景:封装升级脚本,仅运行已升级的钩子
通过脚本对比升级前后的钩子版本,提取出实际升级的钩子ID,再针对性地全量运行这些钩子:
#!/bin/bash set -e # 1. 获取升级前的钩子ID与版本映射 PRE_UPGRADE_MAP=$(pre-commit autoupdate --dry-run | grep -E 'Updating (.*) from (.*) to' | awk '{print $2, $4}') # 2. 执行钩子升级 pre-commit autoupdate # 3. 获取升级后的钩子ID与版本映射 POST_UPGRADE_MAP=$(pre-commit autoupdate --dry-run | grep -E 'Updating (.*) from (.*) to' | awk '{print $2, $4}') # 4. 对比找出已升级的钩子ID UPGRADED_HOOKS=$(comm -13 <(echo "$PRE_UPGRADE_MAP" | sort) <(echo "$POST_UPGRADE_MAP" | sort) | awk '{print $1}') # 5. 对每个升级的钩子执行全量检查 if [ -n "$UPGRADED_HOOKS" ]; then echo "Detected upgraded hooks: $UPGRADED_HOOKS" for HOOK in $UPGRADED_HOOKS; do echo "Running full check for hook: $HOOK" pre-commit run --all-files "$HOOK" done else echo "No hooks were upgraded." fi
可以把这个脚本保存为pre-commit-upgrade.sh,或者封装到Makefile中(比如make pre-commit-upgrade),方便团队统一使用。
2. CI验证场景:精准检测钩子版本变更,针对性全量运行
在CI流程中,通过对比当前提交与上一版本的pre-commit配置文件,仅在检测到钩子版本变更时,对对应钩子执行全量检查:
以GitHub Actions为例,核心步骤脚本如下:
set -e # 1. 导出上一版本的配置文件 git show HEAD~1:.pre-commit-config.yaml > old_config.yaml # 2. 对比配置文件,提取版本变更的钩子ID # 这里通过匹配rev字段变更,关联对应的钩子id UPGRADED_HOOKS=$(diff old_config.yaml .pre-commit-config.yaml | grep -B2 -A2 '^[+-] rev:' | grep '^ id:' | awk '{print $2}' | sort | uniq) # 3. 根据是否有钩子升级,执行不同逻辑 if [ -n "$UPGRADED_HOOKS" ]; then echo "Running full checks for upgraded hooks: $UPGRADED_HOOKS" for HOOK in $UPGRADED_HOOKS; do pre-commit run --all-files "$HOOK" done else echo "No hook upgrades detected, running incremental check." pre-commit run --from-ref HEAD~1 --to-ref HEAD fi
这个脚本会过滤掉配置文件中的无关变更(比如注释、钩子顺序调整),仅针对真正升级了版本的钩子触发全量检查,避免无效执行。
注意事项
- 对于自定义本地钩子(无
rev字段),需要额外添加逻辑识别其变更(比如脚本文件的哈希变更)。 - 可以结合pre-commit的
--config参数指定配置文件路径,适配非标准位置的配置。
内容的提问来源于stack exchange,提问作者Ilia Kurenkov
相关产品推荐
相关产品推荐

