Git hooks is one of the advance features provided by Git, and can be very useful to specify certain rules for your local workflow or as global rules for everyone else.
Overview
Git hooks feature is a mechanism to trigger custom scripts when we interact with Git, either if we are trying to commit changes to our local repository, or if we are pushing changes to a remote server. There are some useful use cases to increase security and prevent unexpected changes on our server, specially if we are working on public repositories. It can also be useful to enforce conventions for commit messages, include git rebase rules, or prevent certain operation based on branch names, user, etc.
Client hooks
These are rules applied locally only, and are specific to the containing repository. They are available under .git/hooks/
folder. Every time we create a new git repo through git init
some sample scripts are created, we can remove the .sample
extension and give it a try. These are bash scripts, but we can use any other language, the only rule is to have an executable file with the expected hook name, and the file must contain the corresponding shebang (e.g. #!/usr/bin/env python
for a Python script)
These are the hooks available for the client:
pre-commit
triggered before writing the commit message, it’s useful to check files and data being committedprepare-commit-msg
triggered before writing the commit message but after the default message is created, it can be useful to customize the default message with some info related to the files and data being committed.commit-msg
triggered after writing the commit message. A very common use case is to evaluate and reject the commit if the message doesn’t follow expected conventionspre-rebase
triggered before performing a rebase taskpost-rewrite
triggered when commits are replaced, for example when —amend or rebase is executed.post-merge
triggered after a successful merge taskpre-push
triggered before pushing changes to a remote referencepre-auto-gc
triggered right before executing garbage collection task, when `git gc —auto` is executed
Client hooks are very personal and limited to the user and project where these hooks are located. Anyhow, it's always a starting point to expand and create some working guidance in order to prevent and keep common mistakes on the client side only.
Server hooks
These are rules applied on the server side. It's a safer way to apply rules for anyone interacting with the Git server (either if we use Github, Gitlab, or any other server). These rules can be applied globally to all the repositories available on the server, or by project. Some use cases can be to ensure conventions for commit messages, reject specific file extensions, make sure none of the updated references are non-fast-forwards, emailing, CI interaction, detect sensitive information, and more.
These are the hooks available for the server:
pre-receive
It takes a list of references that are being pushed fromstdin
; if it exits non-zero, none of them are acceptedupdate
the update script is very similar to the pre-receive script, except that it’s run once for each branch the pusher is trying to updatepost-receive
runs after the entire process is completed and can be used to update other services or notify users
Probably, before creating some scripts and custom operations, it’s better and simpler to check if your current server (Gitlab, Github, etc) provides some of these features with a user-friendly interface. That would save development time, and maintenance time as well.
In any case, it’s good to know there’s a way to customize the server and create our own rules. I found it very useful to implement security features and validations that are not available through Gitlab community edition, and it requires to pay a lot of money for a higher licence that enable this single feature plus a bunch of other features that we are not interested in.
References
Cover image credits:
Technology vector created by vectorjuice - www.freepik.com