带有 Phing 的源代码控制的 Git 钩子
前几天我正在试验Git钩子。这些是您可以在Git中运行某些操作之前执行的脚本。例如,您可能希望确保不运行强制更新,确保存储库文件在合并后具有正确的权限,或者文件在提交前具有ASCII标准名称。
要在Git中使用钩子,您只需将它们添加到存储库中的.git/hooks目录并更改文件的模式以使其可执行。一个新的Git存储库将创建几个示例挂钩文件,可以通过从末尾删除“.sample”并使它们可执行来使用这些文件。有关Git挂钩以及如何使用它们的更多信息,请参阅Git文档中的Git挂钩手册页。
我创建Git钩子的主要原因是确保我的代码在提交之前没有语法错误。我以前要么手动检查,要么使用Jenkins下载存储库并检查代码是否有错误,但后来我意识到在源头停止它们会容易得多。
为此,我创建了一个名为pre-commit的钩子文件,并将其添加到钩子目录中。正如您可能猜到的,这个钩子是在Git中执行提交操作之前运行的。我之前谈到过使用Phing对存储库中的所有PHP和JavaScript文件进行语法检查,所以我在这里只使用了相同的Phing目标。唯一的补充是,如果Phing语法检查失败,我还需要提交操作停止,这可以在钩子文件本身中完成。将有足够的关于Phing输出中失败内容的信息来显示提交失败的原因,因此我不需要在此处打印任何其他内容。这是完整的钩子文件。
#!/bin/sh echo "Parsing PHP and JavaScript files for lint errors." phing -f scripts/build.xml syntaxcheck || exit 1
这按预期工作,我无法将包含语法错误的文件提交到存储库。唯一的问题是,如果我在不同的位置再次检查存储库,我会丢失这个钩子,因为.git目录(因此.git/hooks)中的文件不受源代码控制。这也意味着我无法让从事该项目的其他人遵循相同的做法,因为他们也会错过存储库上的挂钩。经过一番寻找解决方案后,我发现最好的做法是将钩子文件包含在存储库中,然后编写一个脚本来自动将钩子包含到.git/hooks目录中。
我在我的存储库中创建了一个名为githooks的目录,并将我创建的钩子移动到其中,以便可以对其进行源代码控制。我没有从头开始创建脚本,而是决定将githook目标添加到我的存储库中已经存在的Phing构建文件中。该目标具有以下操作:
定义一些指向我的存储库中的.git/hooks目录和githooks目录的属性。
删除现有的.git/hooks目录。
将githooks目录符号链接到.git/hooks,从而替换原来的hooks目录。
在githooks目录中创建一个包含所有可能的钩子文件的文件集。
循环遍历文件集中的文件并确保它们都设置为可执行。这很棘手,需要使用名为chmodsetexecute的次要目标,该目标具有将传递给它的文件名设置为可执行的单一操作。
以下是用于使用自定义Git挂钩设置存储库的两个Phing目标。
有了所有这些,它只是确保每次完成新检出时运行此目标并且现有存储库随此更改更新的情况。这会设置正确的Git钩子,并确保没有人可以提交有语法错误的代码。