Using Git Hooks

Hook into the Git routine and make it do your bidding.

Image

Git hooks are sim­i­lar to SVN hooks; you can exe­cute a script at a point in the Git rou­tine. Git hooks are both local and serv­er-side. The local hooks per­tain to local activ­i­ties, like com­mit­ting, merg­ing, check­ing out, etc. The serv­er-side hooks deal with receiv­ing push­es from a local client.

The scripts that Git hooks exe­cute are stored in the .git/hooks direc­to­ry of your project. In every repos­i­to­ry there are a col­lec­tion of sam­ple hooks that you can rename and use as inspi­ra­tion for your own.

The scripts can be in any lan­guage that sup­port exe­cutable scripts. The sam­ples are most­ly shell scripts, but you can use Perl, Ruby, Python, or some­thing else that is famil­iar to you.

Here are all the hooks avail­able in Git:

  • pre-commit
  • prepare-commit-msg
  • commit-msg
  • post-commit
  • applypatch-msg
  • pre-applypatch
  • post-applypath
  • pre-rebase
  • post-rewrite
  • post-checkout
  • post-merge
  • pre-push
  • pre-receive
  • update
  • post-receive

Local Git Hooks

Local Git hooks reside in the .git/hooks direc­to­ry and are not treat­ed as project files. They are not tracked in the Index and because of that they are not includ­ed when some­one clones a repository.

Because of this there are some lim­i­ta­tions to keep in mind while work­ing with Git hooks. First and fore­most: local hooks are not a reli­able way to enforce poli­cies, like a com­mit mes­sage struc­ture. And, because you are unable to include the con­tents of the .git/hooks direc­to­ry in ver­sion con­trol, you will need to con­sid­er a way to share hooks that you’d like your team to use. 

Here are the local hooks:

  • pre-commit
  • prepare-commit-msg
  • commit-msg
  • post-commit
  • applypatch-msg
  • pre-applypatch
  • post-applypath
  • pre-rebase
  • post-rewrite
  • post-checkout
  • post-merge
  • pre-push

Serv­er-side Hooks

Serv­er-side hooks are set up to kick off scripts when a typ­i­cal remote repos­i­to­ry actions takes place. 

There are only three serv­er-side hooks:

  • pre-receive
  • update
  • post-receive

They all oper­ate around when the serv­er receives a git-push from a client. These are reli­able meth­ods for enforc­ing some sort of repos­i­to­ry or stan­dard. You can run checks, kick of an inte­gra­tion script, test­ing, etc. 

Imple­ment a Git Hook

For our exam­ple we’re going to imple­ment a local hook. We’d like to dis­play a mes­sage after each com­mit, remind­ing us to push our com­mits to the remote repository.

The set­up for this mes­sage will be to use the post-commit hook. This hook is trig­gered after each suc­cess­ful com­mit. For our imple­men­ta­tion, we want the hook to trig­ger and dis­play a mes­sage for us.

There isn’t a sam­ple file for post-commit already in place. That’s okay, we can cre­ate it. 

Cre­ate a new file called post-commit in .git/hooks.

I’m going to use Ruby as the script­ing lan­guage. Remem­ber, Git Hooks can use any exe­cutable script. But I like Ruby so we’ll use that. This Ruby code is as sim­ple as it comes, with just a sin­gle puts statement.

Add this code to the post-commit file:

#!/usr/local/bin
puts "======================="
puts "Please remember to push your commits!"
puts "======================="

With the code in place, we can then save the hook file and set it as executable.

$ chmod +x post-commit

Test it by mak­ing a change to our project and cre­at­ing a com­mit. If you see the mes­sage, it worked!

If you didn’t, check your code, that the hook file is exe­cutable, and that you have it prop­er­ly named.

In anoth­er arti­cle I’ll talk about trig­ger­ing hooks on the server.