Breaking the build never feels good. Thanks to git’s new pre-push hook we can force ourselves to run our tests before we push to master, and prevent any odd punishments our current team has setup.
As of git version 1.8.2 which was released in April 2013, you now have the ability to execute a script on a push, and prevent the push from occuring if your script exits with a failure.
If you’re running OS X 10.9 Mavericks, and you have Xcode 5’s command line tools installed, you will already have a version of git that is pre-push hook ready.
Otherwise if your version is less than 1.8.2, you will need to download, and ensure
/usr/local/git/bin is in your path, by adding
export PATH=/usr/local/git/bin:$PATH to your
You can test if you have installed correctly with
which git and
Enabling the pre-push hook
For each git repository you can find the hooks in the
.git/hooks directory. All it takes for a git hook to run, is for there to be an executable file with the appropriate name within this directory. The list of available hooks are:
To enable the pre-push hook, just create
Editing your pre-push hook
If the pre-push script exits with a failure (a return status of non-zero) then the push will do nothing. A very basic script to remind yourself that you should run your tests before pushing would look like this:
1 2 3 4 5 6 7 8 9
This is a pretty silly use-case for pre-push, below are some more practical uses.
Using pre-push as a safety net
Sometimes I want the ability to write a comment on a piece of code/spike that I am doing, and make sure it never goes beyond my machine. Below is a pre-push example that will search the current source for the string ‘DONT PUSH ME’ and if found, will prevent the push and display in which commit the ‘DONT PUSH ME’ flag was introduced.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Using pre-push to only push on successful execution of tests
Below is an example pre-push script that let’s us specify a branch to ‘protect’ so that our tests will only run if there are commits to push and we are on ‘master’. Also because pre-push will execute regardless of if there are commits to push or not, the script ensures we don’t fire off a lengthy test command, only to find out we actually didn’t need to.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
Bypassing the pre-push hook
git push --no-verify
If you want to skip your pre-push hook from executing, you can run this and feel dirty about it ;)
Git’s included example
If you have created a repo with a version of git later than 1.8.2, then git has already set you up with a sample pre-push script
.git/hooks/pre-push.sample. This script prevents pushing if any of the ‘to be pushed’ commits begin with ‘WIP’, and also details the parameters that are passed into the script.
That’s a wrap
You can find all of the scripts here https://github.com/raven/git-prepush-recipes. Please submit pull requests if you spot any issues, or if you have any pre-push scripts of your own.
If you have any questions or comments, ping me on twitter