git hook语法检查

时间:2010-09-15 16:51:00

标签: git

尝试为git存储库创建一个php语法检查钩子。当我发现一个完全符合这一要求的代码片段时,我很高兴。

但似乎代码段脚本有一个缺陷。它执行

git diff-index --cached --name-only HEAD

获取索引中的文件列表。现在它为该列表上的每个文件运行php -l。缺陷是工作副本和临时区域之间的文件可能不同。如果暂存区域php有语法错误,但工作副本版本没有,则没有找到语法错​​误,并且提交成功,这是要防止的事情。

这是一个难以解决的问题,还是有办法在每个文件的登台版本上运行php -l?

3 个答案:

答案 0 :(得分:7)

我很高兴使用这个php syntax validation hook。希望它也能满足您的需求。

它使用git diff-index --cached --full-index

答案 1 :(得分:3)

我不确定这里是否有问题。

您提到的代码段可能来自博文Don’t Commit That Error 它包括:

  

接下来,我们使用一些参数调用git diff-index   首先,我们添加--cached告诉Git我们只想要提交的文件
  然后,我们添加--name-only告诉Git只输出正在提交的文件的名称。

似乎即将提交的文件正是预提交钩子想要检查的文件 即使它们与工作目录中的文件不同,也是要提交的版本(在索引中)。它是将发送到php -l进程的相同版本。


实际上,问题不在于git diff-index本身(有或没有--full-index),就像您在索引中读取文件内容一样

exec("php -l " . escapeshellarg($file), $lint_output, $return);
result=$(git cat-file -p $sha | /usr/bin/env $PHP_BIN -l 2>/dev/null)

使用 git cat-file 是关键,访问Git仓库中的对象(即不在“工作目录”中)

答案 2 :(得分:0)

原因预提交挂钩不适合在团队中工作,您应该使用服务器端安装的预接收挂钩拒绝所有提交无效的PHP语法和编码标准不正确。

我为该广告创建了预接收 python脚本:

# A server-side git hook script for checking PHP syntax and validating coding standard
# Depends on: PHP_CodeSniffer (http://pear.php.net/package/PHP_CodeSniffer/)
# Install: copy this script to <server side repo location>/hooks/pre-receive
#!/usr/bin/python

import os
import sys
oldrev, newrev, ref = sys.stdin.read().strip().split(' ')
test_file = os.popen('mktemp').read().strip()
coding_standards = 'PSR2'
for line in os.popen('git diff --name-only %s %s' % (oldrev, newrev)).readlines():
    extension = line.split('.')[-1].strip()
    file_name = line.strip()

    if(extension == 'php'):
        os.system("git cat-file -p %s:%s > %s" % (newrev, file_name, test_file))
        if 0 != os.system('php -l ' + test_file + ' > /dev/null'):
            print "PHP Syntax error in file %s" % (file_name)
            sys.exit(1)

        if 0 != os.system("phpcs -n --standard=%s %s" % (coding_standards, test_file)):
            print "Coding standards fail in file %s" % (file_name)
            sys.exit(2)
相关问题