You need to enable JavaScript to run this app. 自定义目录结构下Docker环境中GrumPHP pre-commit钩子未生效
优惠活动
大模型
产品
解决方案
定价
更多

自定义目录结构下Docker环境中GrumPHP pre-commit钩子未生效

异常根因
  • 路径映射错位导致待检查文件列表为空
    Git提交触发的pre-commit钩子运行在项目根目录(即.git所在层级),拉取到的暂存区文件路径都是以app/为前缀的仓库根目录相对路径(例如app/src/Controller/Test.php)。但钩子调用容器内的GrumPHP时,GrumPHP的默认工作目录就是app目录本身,相当于它需要匹配的文件路径变成了app/app/src/Controller/Test.php——这个路径在容器内完全不存在。
    GrumPHP的任务执行逻辑是:如果从diff中提取到的待检查文件列表为空,会直接返回成功,不会抛出“找不到目标文件”的异常,因此出现了“提交时显示校验通过,但实际未执行任何检查”的现象。
  • 容器环境变量传递失效
    钩子脚本中通过export设置的GRUMPHP_GIT_WORKING_DIR仅在宿主shell中生效,docker exec命令默认不会将宿主环境变量传入容器进程,容器内的GrumPHP根本接收不到这个路径配置。同时grumphp.yml中配置的GRUMPHP_GIT_WORKING_DIR: "../"、GRUMPHP_GIT_REPOSITORY_DIR: "../.git/"这类相对路径,基准是容器内GrumPHP进程的启动目录,极易因为容器工作目录不一致出现路径错位。
  • 手动运行与钩子流程的执行逻辑差异
    手动在容器内运行vendor/bin/grumphp run时,GrumPHP会默认扫描当前工作目录下所有符合规则的文件,完全不依赖Git传递的暂存文件路径,因此可以正常检出代码问题。但pre-commit流程调用的是git:pre-commit子命令,核心逻辑是仅检查diff中匹配到的暂存文件,一旦路径错位没有匹配到有效文件,就会直接通过校验。
修复方案
  • 调整钩子的diff路径适配逻辑
    拉取到暂存区diff后,移除diff中所有文件路径的app/前缀,让路径适配GrumPHP在容器内的app工作目录,修改后的钩子diff处理片段如下:
    DIFF=$(git -c diff.mnemonicprefix=false -c diff.noprefix=false --no-pager diff -r -p -m -M --full-index --no-color --staged | cat)
    # 移除diff文件路径中的app/前缀,匹配app目录下的相对路径
    DIFF=$(echo "$DIFF" | sed -E 's|^(diff --git [ab]/)app/|\1|g')
    
  • 固定容器内的运行工作目录
    修改grumphp.yml中的EXEC_GRUMPHP_COMMAND,通过docker exec的-w参数强制指定容器内的运行目录,避免依赖容器默认WORKDIR出现路径偏差,示例配置:
    git_hook_variables:
        EXEC_GRUMPHP_COMMAND: docker exec -w /容器内app目录的绝对路径 php-fpm
    
  • 清理无效配置
    1. 删除钩子脚本中无效的export GRUMPHP_GIT_WORKING_DIR=...代码,这些变量不会传入容器,仅会造成逻辑误导
    2. 移除grumphp.yml的environment.variables下所有依赖相对路径的配置,GrumPHP会自动基于当前工作目录定位.git目录和配置文件,无需手动指定路径。
  • 重新生成钩子
    修改完配置后,删除原有的.git/hooks/pre-commit文件,重新在容器内运行vendor/bin/grumphp git:init生成新的钩子,再按照上述逻辑调整diff路径替换规则即可。

内容的提问来源于stack exchange,提问作者Bogdan Dubyk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.03 16:24:02