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 committed
  • prepare-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 conventions
  • pre-rebase triggered before performing a rebase task
  • post-rewrite triggered when commits are replaced, for example when —amend or rebase is executed.
  • post-merge triggered after a successful merge task
  • pre-push triggered before pushing changes to a remote reference
  • pre-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 from stdin; if it exits non-zero, none of them are accepted
  • update 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 update
  • post-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

Git - Git Hooks
Server hooks | GitLab
Documentation for GitLab Community Edition, GitLab Enterprise Edition, Omnibus GitLab, and GitLab Runner.
Enforcing policy with pre-receive hooks - GitHub Docs
Use pre-receive hooks to enforce workflow standards within your organization. Pre-receive hooks require code to pass a pre-defined set of quality checks before the push is accepted into the repository.

Cover image credits:

Technology vector created by vectorjuice - www.freepik.com