最简单可控的 pre-commit 验证方式是直接在 .git/hooks/pre-commit 中写 shell 脚本调用 composer validate,需 cd 到仓库根目录、用 #!/bin/sh、优先本地 composer.phar、加 --strict --no-interaction --no-check-publish 参数,失败时 exit 1,并建议仅在 composer.json 变更时执行。

直接在 .git/hooks/pre-commit 里写 shell 脚本调用 composer validate 是最简单、最可控的方式,不需要额外依赖或配置文件解析——只要项目根目录有 composer.json,它就能立刻起效。
pre-commit 脚本必须 cd 到项目根目录再执行 composer 命令
Git 钩子运行时的当前工作目录不一定是项目根目录(比如从子目录下执行 git commit),直接调用 composer validate 可能报错 Could not find composer.json。
- 务必第一行加
cd $(git rev-parse --show-toplevel)切到 Git 仓库根目录 - 推荐用
#!/bin/sh而非#!/usr/bin/env bash,避免 macOS 或 CI 环境中bash版本不兼容 - 如果项目用了本地
composer.phar,优先调用php composer.phar validate,比全局composer更可靠
composer validate 必须加 --no-interaction 和 --strict
composer validate 默认遇到缺失 license 字段等警告会暂停等待输入,导致 commit 卡死;不加 --strict 则跳过 PSR-4 映射路径是否存在、autoload 是否可加载等关键检查。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 正确命令是:
composer validate --strict --no-interaction --no-check-publish -
--no-check-publish省掉对 Packagist 的网络请求,防止因网络抖动失败 - 若验证失败,脚本末尾必须
exit 1,否则 Git 会无视错误继续提交 - 不要用
php -l composer.json替代——PHP 解析器会把 JSON 当 PHP 代码读,字段含@或注释时直接报错
只在 composer.json 变更时运行验证(可选但推荐)
每次 commit 都跑 composer validate 没必要,尤其在大型单体仓库中。可以先判断 composer.json 是否在本次暂存区里有修改。
- 加一行:
if ! git diff --cached --quiet -- composer.json; then - 把
composer validate放在这个if块内,提高响应速度 - 注意:这个判断不适用于
composer.lock自动更新场景——那种情况需要另配pre-push钩子拦截未暂存的 lock 变更
Windows 下要注意 grep 和换行符兼容性
Git for Windows 自带的 Bash(Git Bash)里 grep 行为和 Linux 有差异,且脚本若用 Windows 换行符(CRLF)保存,#!/bin/sh 可能无法识别,直接报 bad interpreter 错误。
- 用 VS Code 或 Notepad++ 把
pre-commit文件保存为 LF(Unix)换行格式 - 避免在脚本里直接用
grep -q '^ M'查composer.lock状态,改用git status --porcelain=2 composer.lock | head -n1更稳妥 - 如需跨平台统一,可用
sh -c 'git status --porcelain composer.lock | grep -q "^ M"'包一层
真正容易被忽略的是钩子权限和 vendor/ 的 .gitignore 状态——chmod +x .git/hooks/pre-commit 忘了设就完全不生效;而如果 vendor/ 没被忽略,composer install 在钩子里执行时会尝试写入未跟踪目录,导致钩子崩溃。

















