Windows下Git预提交钩子:用PHP_CodeSniffer检测暂存文件
我来帮你搞定Windows下Git预提交钩子结合PHP_CodeSniffer的需求!结合你的情况,我分步骤给你提供可行的实现方案,完全适配Windows环境:
第一步:解决Windows下筛选PHP文件的问题
Windows没有自带grep,但我们可以用系统自带的工具替代:
- CMD环境:用
git diff --cached --name-only | findstr /i "\.php$",其中/i忽略大小写,\.php$精准匹配以.php结尾的文件 - PowerShell环境:用
git diff --cached --name-only | Where-Object { $_ -match '\.php$' }
第二步:编写预提交钩子脚本
推荐用PHP写钩子脚本(毕竟你熟悉PHP,处理文件路径和命令更灵活),步骤如下:
- 在项目根目录的
.git/hooks文件夹中,创建一个无后缀的文件pre-commit(注意不能是pre-commit.php或pre-commit.bat) - 将以下代码复制到这个文件中:
#!/usr/bin/env php <?php // 1. 获取所有暂存的文件列表 $stagedFiles = []; exec('git diff --cached --name-only', $stagedFiles); // 2. 筛选出其中的PHP文件(忽略大小写) $phpFiles = array_filter($stagedFiles, function ($file) { return preg_match('/\.php$/i', $file); }); // 3. 如果没有PHP文件,直接放行提交 if (empty($phpFiles)) { echo "✨ No PHP files staged, skipping PHP_CodeSniffer check.\n"; exit(0); } // 4. 构造PHP_CodeSniffer检查命令(自动处理带空格的路径) $filesArg = implode(' ', array_map('escapeshellarg', $phpFiles)); $command = "phpcs --standard=PSR2 {$filesArg}"; // 5. 执行检查并输出结果 echo "🔍 Running PHP_CodeSniffer check on staged files:\n"; passthru($command, $exitCode); // 6. 根据检查结果决定是否允许提交 if ($exitCode !== 0) { echo "\n❌ PHP_CodeSniffer found issues. Commit aborted.\n"; exit(1); // 非0退出码会阻止Git提交 } echo "\n✅ PHP_CodeSniffer check passed. Proceeding with commit.\n"; exit(0);
第三步:配置与测试
- 确保
php和phpcs命令在系统PATH中(或者替换成绝对路径,比如C:\php\php.exe和C:\php\phpcs) - 给钩子文件添加执行权限:如果用Git Bash,运行
chmod +x .git/hooks/pre-commit;Windows CMD环境下直接保存即可,Git会自动识别执行 - 测试验证:暂存一个不符合PSR2规范的PHP文件,执行
git commit,会看到CodeSniffer的错误提示且提交被阻止;修正代码后再次提交就能正常通过
备选方案:用Batch脚本实现
如果你更习惯Batch,也可以用下面的代码(同样保存为无后缀的pre-commit):
@echo off setlocal enabledelayedexpansion :: 获取暂存的PHP文件 set "php_files=" for /f "delims=" %%f in ('git diff --cached --name-only ^| findstr /i "\.php$"') do ( set "php_files=!php_files! "%%f"" ) :: 无PHP文件则放行 if "!php_files!"=="" ( echo ✨ No PHP files staged, skipping PHP_CodeSniffer check. exit /b 0 ) :: 执行CodeSniffer检查 echo 🔍 Running PHP_CodeSniffer check... phpcs --standard=PSR2!php_files! :: 根据返回码判断是否阻止提交 if %errorlevel% neq 0 ( echo ❌ PHP_CodeSniffer found errors. Commit aborted. exit /b 1 ) else ( echo ✅ PHP_CodeSniffer check passed. exit /b 0 )
内容的提问来源于stack exchange,提问作者online Thomas
相关产品推荐
相关产品推荐

