Git hooks are similar to SVN hooks; you can execute a script at a point in the Git routine. Git hooks are both local and server-side. The local hooks pertain to local activities, like committing, merging, checking out, etc. The server-side hooks deal with receiving pushes from a local client.
The scripts that Git hooks execute are stored in the
.git/hooks directory of your project. In every repository there are a collection of sample hooks that you can rename and use as inspiration for your own.
The scripts can be in any language that support executable scripts. The samples are mostly shell scripts, but you can use Perl, Ruby, Python, or something else that is familiar to you.
Here are all the hooks available in Git:
Local Git Hooks #
Local Git hooks reside in the
.git/hooks directory and are not treated as project files. They are not tracked in the Index and because of that they are not included when someone clones a repository. They are truly just local.
Because of this there are some limitations to keep in mind while working with Git hooks. First and foremost: local hooks are not a reliable way to enforce policies, like a commit message structure. And, because you are unable to include the contents of the
.git/hooks directory in version control, you will need to consider a way to share hooks that you’d like your team to use.
Here are the local hooks:
Server-side Hooks #
Server-side hooks are set up to kick off scripts when a typical remote repository actions takes place.
There are only three server-side hooks:
They all operate around when the server receives a
git-pushfrom a client. These are reliable methods for enforcing some sort of repository or standard. You can run checks, kick of an integration script, testing, etc.
Implementing a Git Hook #
For our example we’re going to implement a local hook that will display a message before each commit, reminding us to push our commits to the remote repository.
The setup for this message will be to use the post-commit hook. This hook is triggered after each successful commit. For our implementation, we want the hook to trigger and display a message for us.
My usual first step would be to open the sample hook (
hookname.sample) but for post-commit there isn’t a sample hook in the default installations of Git.
But let’s open another one just to see what it looks like. The hooks are located in
.git/hooks inside of your project directory. I like to use Vim to edit, but you can open this is any editor you’d like.
$ vim .git/hooks/pre-commit.sample
We see that this hook is written as bash script. Inside of it we can put rules for what should happen before a commit is created. This file has a lot of extra stuff in it, including comments to explain what the hook does and how to enable it (by renaming it, removing the
But let’s quit out of that and start working on our own hook.
Creating the Hook File
We need to first create a new file called
post-commit (no file extension necessary in
We are going to use Ruby as our scripting language. Remember, Git Hooks can use any executable script. I like Ruby so we’ll use that.
Add this code to the new 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
And now let’s test it by making a change to our project and creating a commit. If everything is set up properly, anytime you create a commit in this repository, you will see that message appear!
Post-Push Hooks #
If want to have hooks that are triggered server side but you use a service like Github, then you can take advantage of the Github implementation. Almost all hosted Git services have something similar.
- Go to your repository at Github
- Choose Settings
- Choose Webhooks
Any hooks you had here will be triggered using the post-receive hook. The trigger will happen after Github successfully receives a push. You can do anything here, like hit a URL of a web service that triggers something on your server (like a build or deployment or something else).