composer怎么配置git hooks_composer pre-commit脚本集成【钩子】

在 composer.json 中添加 pre-commit 钩子需借助 brainmaestro/composer-git-hooks:dev 依赖该包,scripts 中定义 “pre-commit” 命令,通过 “post-install-cmd” 和 “post-update-cmd” 调用 cghooks install 自动生成 .git/hooks/pre-commit 文件。

composer怎么配置git hooks_composer pre-commit脚本集成【钩子】

composer.json 里怎么加 pre-commit 钩子

Composer 本身不执行 Git hooks,pre-commit 是 Git 的钩子,必须靠第三方工具或手动集成。最直接的做法是用 composer installcomposer update 触发钩子安装,但前提是项目里已引入支持钩子的包(比如 brainmaestro/composer-git-hooks)。

实操建议:

  • composer.json"require-dev" 中添加 "brainmaestro/composer-git-hooks": "^2.8"
  • "scripts" 下定义钩子命令,例如:"pre-commit": "php-cs-fixer fix --dry-run --using-cache=no"
  • 加一个 "post-install-cmd""post-update-cmd" 脚本,调用 vendor/bin/cghooks install(这是 composer-git-hooks 提供的命令)
  • 确保 .git/hooks/pre-commit 文件被生成且可执行;如果没生成,手动运行一次 vendor/bin/cghooks install

为什么 pre-commit 脚本不运行

常见现象:改完代码 git commit,什么都没发生,也没报错 —— 实际上钩子根本没触发。原因通常是:.git/hooks/pre-commit 文件不存在、不可执行,或内容被覆盖。

排查要点:

  • 检查 .git/hooks/pre-commit 是否存在,权限是否为 755(Linux/macOS)或对应可执行状态(Windows 需 .bat.ps1
  • 确认该文件内容不是空的,也不是原始 Git 模板(含 exit 1 或注释开头的默认内容)
  • 如果用了 husky 或其他 Node 工具管理 hooks,它会覆盖 Composer 工具生成的脚本 —— 二者不能混用
  • composer-git-hooks 默认只在 post-install-cmdpost-update-cmd 时写入钩子,首次克隆仓库后没运行 composer install 就不会生效

pre-commit 里跑 php-cs-fixer 或 phpstan 报错路径不对

典型错误信息:Could not open input file: vendor/bin/php-cs-fixerPHP Fatal error: Uncaught Error: Class 'PhpCsFixerFinder' not found

本质是钩子脚本执行时工作目录不是项目根目录,或未加载 Composer 自动加载器。

解决办法:

  • 所有命令都用相对路径调用,例如 ./vendor/bin/php-cs-fixer(注意前面的 ./
  • 避免在 pre-commit 脚本里用 cd 切换目录,Git hooks 默认在 Git 工作区根目录执行,但某些环境(如 Windows Git Bash)可能 cwd 不稳定
  • 若用 phpstan,加 --configuration=phpstan.neon 显式指定配置路径,避免因相对路径解析失败找不到配置
  • 不推荐在钩子里直接 require vendor/autoload.php 写 PHP 脚本 —— 可维护性差,也容易出 autoloader 冲突

CI 环境下 pre-commit 被跳过,但本地又想强制校验

Git hooks 天然只在本地生效,CI(如 GitHub Actions)完全不走 .git/hooks/。所以别指望 CI 会自动跑你的 pre-commit 脚本。

正确做法是把校验逻辑复用到 CI 流程中:

  • pre-commit 里实际执行的命令(如 ./vendor/bin/php-cs-fixer fix --dry-run)单独抽成一个 composer script,比如 "check-style"
  • CI 的 job 步骤里显式运行 composer run check-style
  • 本地开发时,仍靠 pre-commit 钩子自动触发;CI 则靠明确命令保证一致性
  • 注意:不要在 pre-commit 里做耗时操作(如全量 phpstan analyse),它会拖慢每次提交;CI 才适合跑完整扫描

钩子真正起作用的地方,是开发者日常小步提交时的即时反馈。一旦依赖它做复杂检查,反而容易被绕过或误关 —— 这点比技术实现更关键。