2010-09-15 113 views
7

试图为git仓库做一个php语法检查钩子。我很高兴当我发现一个代码片段完全做到这一点。git钩子语法检查

但似乎该片段脚本有缺陷。它执行

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

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

这是一个不平凡的问题要解决,还是有一些方法可以在每个文件的分期版上运行php -l?

回答

7

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

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

+0

+1为工作钩子。 – VonC 2010-09-16 06:59:12

+0

是的,这比文章中的钩子要好得多。 – zedoo 2010-09-21 19:31:23

+0

挂钩非常好,但它需要略微修改,所以我可以使用它。由于“剪切”命令,我无法获得正确的文件名和扩展名 – cwhsu 2014-09-26 03:31:18

2

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

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

接下来,我们称之为git diff-index有几个参数。
首先,我们添加--cached告诉Git我们只想要提交的文件
然后,我们添加--name-only来告诉Git只输出提交文件的名称。

看起来即将提交的文件恰好是预先提交的钩子要检查的文件。
即使它们与工作目录中的文件不同,它们的版本(在索引中)也将被提交。这是相同的版本,将发送到php -l进程。


其实,这个问题是不是在git diff-index本身(带或不带--full-index)是你会在索引

  • "PHP Advent 2008" hook只会尝试读取文件内容方式从其名称访问文件(有访问工作副本的风险)
 
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回购的对象(即不在“工作目录”)

+0

是的,这就是我说的代码。在$输出中,您将获得要提交的文件列表,并保持正确。但我认为你最后一句话是错的。这是发送到php -l的工作拷贝版本,而不是暂存区版本。这是一个错误。通过takehin连接的钩子似乎做得更好。 – zedoo 2010-09-16 06:30:27

+0

@zedoo:我已经更新了我的答案,以反映这里的实际问题(不是'git diff-index') – VonC 2010-09-16 06:57:56

+0

是的,确切地说。 +1;) – zedoo 2010-09-16 08:13:54

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) 
+2

链接已损坏:-( – 2014-09-05 10:24:51