Pre-commit hook in Git: Running PHPUnit
|
|
Pre-commit hooks in git are one of those things you hardly think about but can help you automate tasks and do last-minute checks. A good example of this is running unit tests before commits, to make sure nothing broke; or checking your files using PHP_CodeSniffer.
With DocBlox I use them to run my unit tests as I personally believe these should be ran (and fixed!) before any commit.
Please note: contrary to Subversion pre-commit hooks are those used by Git installed locally. This is quite logical but makes it a little harder to enforce certain policies.
What is a hook in Git?
Hooks in Git are, as with Subversion, command line scripts which are executed at a pre-determined moment. Because these are plain scripts they enable you to write the intended functionality in any programming language.
In this article we will be writing a pre-commit hook for use under Linux. Under Windows you will need to copy the code into a file different from your hook-file and invoke that using the following command:
php -f <name of file>That will ensure execution under Windows.
In this article we will only talk about the Pre-commit hook; though Git knows a total of 16 different hooks at time of writing. All these hooks are used in the same way and should pose no challenge after reading this.
The Pre-commit hook is a script that runs before your commit is actually resolved; it is possible to abort the commit if an exit code other than 0 is provided. More on this later in this article.
All client-side hooks (git actually has some server-side hooks as well) can be found in the .git/hooks folder of your project. During initialization of your repository has your folder been populated with example hooks; among which the pre-commit. These sample hooks are disabled and can be enabled by removing their .sample extension.
We will do no such thing; we intend to create a new file.
Creating a new hook
A hook in Git must:
- have the exact name as specified for the intended hook; which is in this case
pre-commit(if you have no such file, create it now) be executable; it is acceptable to set the permissions of a hook to 0×777, which can be done using the following command
chmod 777 .git/hooks/pre-commit
After you have created the new file for your hook (you did do this by now, right?) we start by adding the first two and most important lines of code:
#!/usr/bin/php
<?php
That’s it! You do not need any more to start creating your own hook using PHP code.
Making it useful: Adding automated unit tests
Right. Now we need to add something useful. Let’s add the possibility for automated unit testing; which aborts the build when a test has failed!
The most basic form of this is:
exec('phpunit', $output, $returnCode); // cwd is assumed here
if ($returnCode != 0) { echo implode(PHP_EOL, $output); }
die($returnCode);
This code executes phpunit and outputs the test results whenever a test has failed.
By returning phpUnit’s own error code we automatically return a non-zero value when the tests have failed. This then results in an aborted commit.
It is that simple.
Full version
To show you what is possible I have included my own pre-commit hook as a Gist:
What is next?
I intend to follow up on this post with another which will show you how to add support for PHP_CodeSniffer; which only checks the files that you have just committed.
See you back next time!

One Response to “Pre-commit hook in Git: Running PHPUnit”
Nice post
Leave a Reply