如何编程区分pre-commit的两类失败:自动修复与需手动处理?
区分pre-commit两种失败场景:自动修复完成 vs 需要手动处理
pre-commit默认用退出码0表示成功,1表示任意失败,但确实可以通过以下几种方式区分两种失败情况:
解析钩子输出+检查文件状态
自动修复类的钩子(比如autopep8、black)运行后,通常会在输出里明确提到修改了文件;而需要手动处理的钩子(比如flake8的E501错误)只会抛出错误提示,不会改动文件。
你可以在运行pre-commit后,先检查钩子的stdout/stderr输出关键词,再用git diff对比运行前后的文件状态:如果有文件变更,说明是自动修复完成的情况;如果无变更但退出码为1,就是需要手动处理的问题。给钩子加自定义包装脚本
针对需要区分的钩子,写一个简单的包装脚本,让它根据是否修改了文件返回不同的退出码。比如:
以autopep8为例,写一个autopep8-wrapper.sh脚本:#!/bin/bash # 执行autopep8自动修复 autopep8 --in-place "$@" base_exit=$? # 检查目标文件是否被修改 git diff --quiet "$@" if [ $? -eq 1 ]; then exit 2 # 用退出码2标记“自动修复完成” else exit $base_exit # 原退出码对应“需要手动处理” fi然后在
.pre-commit-config.yaml里替换原钩子为这个脚本:repos: - repo: local hooks: - id: autopep8-wrapper name: autopep8 (wrapped) entry: ./scripts/autopep8-wrapper.sh language: script types: [python]这样你的程序就能通过退出码0(成功)、1(需要手动处理)、2(自动修复完成)来区分三种情况。
用Python API细粒度控制
如果是用Python代码调用pre-commit,可以直接用pre-commit的官方API,获取每个钩子的执行细节:import git from pre_commit.main import main def check_pre_commit_status(): repo = git.Repo(".") # 记录初始文件差异 initial_diff = repo.git.diff() # 运行pre-commit exit_code = main(["run", "--all-files"]) if exit_code == 0: print("所有检查通过") return # 对比文件变化 final_diff = repo.git.diff() if final_diff != initial_diff: print("钩子已自动修复问题,需重新提交") else: print("存在需要手动修复的问题")这种方式可以直接在代码里判断两种失败场景,不需要额外处理脚本。
内容的提问来源于stack exchange,提问作者odigity
相关产品推荐
相关产品推荐

