Git Hook que es Development

Git Hooks: What you Need to Know to Get the Most Out of Them

14/03/23 9 min. read

A few months ago we were talking about what is Git, how to learn to get the most out of it, and how to use it for repository management and version control in collaborative environments 💡.

Today, we want to go a step further and delve into .git/hooks. To do so, we are going to know what they are, what they are for, and how to use them to improve the quality of our code automatically. The aim is none other than to unify the formatting criteria so that when we work in collaboration with other developers, we can spend more time on the logic of our developments.

What are .git/hooks and what are they for? 🤔

Hooks are an intrinsic feature of Git.

They are scripts that Git runs before or after certain events like commit, push, or receive. So, for example, if we run the command ‘git. commit’, what Git will do is automatically look for a hook that matches this event. And if there is, it will execute it.

How are .git/hooks grouped? 👇

Basically, hooks are grouped in execution in two parts:

On the customer side, in which we find three types:

  • Committing-Workflow: pre-commit, prepare-commit-msg, commit-msg
  • Email Workflow: applypatch-msg, pre-applypatch, post-applypatch
  • Other: pre-rebase, post-rewrite, post-merge, pre-push, pre-auto-gc

Server-side:

  • Server-side: pre-receive, update, post-receive.

How do .git/hooks work? 🙌

When a repository is initialized, the .git/hooks folder is automatically created with a number of examples. It is important to note that this folder will be hidden.

How do .git/hooks work

For a hook to be executable, we must remove the ‘.sample’ extension. By default, they have execution permission, as long as we have not created it from scratch. In that case, we will have to assign this permission to it:

$ chmod +x <nombre_hook>

Normally bash, shell, or Python are used for these scripts, but we can create them with any language we want. However, there is only one requirement: we will have to indicate in the script header the path of the interpreter we are going to use so that the system knows how to execute it:

  • #!/bin/sh
  • #!/usr/bin/env Python
  • #!/usr/bin/env ruby

Hooks beginning with ‘pre-‘ will be executed before such actions, as opposed to those beginning with ‘post-‘ which will be executed after. Each of them has a use: the first one can be used to make certain checks before the action; while the second one is used to perform subsequent actions such as notification, directory cleanup, etc.

When to use .git/hooks? 👀

Let’s start from the premise that casuistry can be very broad. That is why, for now, we are going to focus on the part related to commits so that we can standardize and automate the formatting of our code. This will also allow us to establish certain requirements before committing our changes.

Reviewing the hooks related to the ‘commit’ action, we can find the following cases:

  • pre-commit.

This hook will be executed whenever the ‘git commit’ command is executed. It is the ideal script if you are looking to run a test of the code or apply certain style rules. A non-zero exit code will abort the operation.

*** For this particular case, we can use an existing Python-based framework: ‘pre-commit’. This will provide us with a lot of functionality while saving us a lot of time.

  • prepare-commit-msg.

It will be executed after the pre-commit and is appropriate to set an automatic commit message based on the branch from which it is developed. In this case, a non-zero exit code will also abort the operation.

  • commit-msg.

It will be executed after the user has entered a ‘commit’ message. What it will allow us to do is to add a warning in case the message does not conform to the established standards. As in the previous cases, a non-zero exit code will abort the operation.

  • post-commit.

It will be executed after ‘commit-msg’ and its main function is to send notifications. In this case, the output code does not affect the result.

*** The fact that the pre-checks generate an error code means that the commit will not be performed, and will therefore be prevented until the condition is met.

Examples of use: install the ‘pre-commit’ framework

We are going to install the ‘pre-commit’ framework via the package manager.

To do this, we will follow the steps below:

  • Run $ pip install pre-commit.
  • We will have to install the hook in our repository using the command $ pre-commit install.
  • This will create a new hook called ‘pre-commit’ whose function is to execute the ‘.pre-commit-config.yaml’ file in our root folder. The following image shows the contents of that hook:
git hooks examples

The YAML file it refers to does not exist yet, but that’s not a problem because we will set it up in the next step.

We can generate it as an empty file, e.g. by $ touch .pre-commit-config.yaml

  • We can then edit it with the editor of our choice and fill it with the information we want. The syntax should be:

repos:

–   repo: <repo_url>

    rev: <version_number>

    hooks:

    –   id: <hook_id>

        name: <message information for hook>

        language: <language_used>

        entry: <input_value>

        args: <arguments or options to define the hook>

        stages: <stage_execution>

*** At this point, we have detailed the most commonly used options for each hook, but there are more.

Continuing with this same example, let’s start with the basic pre-commit-hooks. Common to many developments, these are the ones that perform all kinds of standard checks such as removing whitespace, changing line endings, checking the syntax of json/yaml files, or avoiding committing to master and main branches.

Once we have done this, the end result should look something like this:

Gi hooks use cases

And executing the commit will result in this:

git hooks examples

One step further 👟 

Continuing with the examples, let’s imagine that we are part of a team of developers who provide certain services to their clients. And going further, let’s suppose that in this team we work through requests or incidents opened through ticketing tools.

In this case, it is logical to think that we would want to include a mandatory reference to the “CLIENT_ID-xxx” responsible for opening our ticket, as well as the type of development (‘ref: ‘ or ‘bug: ‘). What this will allow us to do, in a simpler way, is to track the evolution of the code and its relationship with the requests that we may receive.

To do this, the first thing we would have to do would be to check the commit messages from the development team. And how can we do that? In a very simple way: using the ‘commit-msg’ option, since this hook allows us to evaluate the commit messages.

To proceed with the installation:

Ejecutamos $ pre-commit install -install-hook -t commit-msg.

This will create another hook called ‘commit-msg’ (in the .ghit/hooks folder) with this configuration:

commit msg git hooks

As you can see, in this case, it also refers to the same YAML configuration file as above.

The next step is to add the information we need for this new hook in this file (.pre-commit-config.yaml). As this is a script, it will be a ‘local’ repo and we will do it using “language: pygrep”. This will allow us to customize how the ‘commit used’ message will be checked. To give an example:

git hooks repos

As can be seen, in this case, using regular expressions we can check the content of the message.

If we commit without including the required information, the result would look something like this:

Git Hooks 3

Whereas if we do so by fulfilling all the required criteria, the regex expression would be validated correctly and therefore pass the check:

git hooks example

Case in point: developing with Terraform

Finally, let’s assume that we are developing with Terraform. In this case, if what we are looking for is to perform checks on our code and a series of additional checks such as security, formatting, etc., we could use a specific repo.

For this, we will use one that has already been created.

We will import it as a ‘repo’ and add those hooks to our YAML configuration file. The result should look something like this:

git hooks example developing with terraform

Then if we perform a commit, the checks would be something similar to what you can see in this image:

Git Hooks 6

As you can see, an error message is displayed. The reason is that a variable was declared without identifying its type. However, once corrected, it will pass all the tests and perform the commit.

Git Hooks terraform

👁 Everything we have seen here is just a small sample of the capabilities of hooks and all the benefits we can get from them. Therefore, from Santander, we encourage you to continue delving into the subject to learn more about it and take advantage of it in your day-to-day work. Because hooks can be very useful, especially if we are talking about large teams in charge of large volumes of work.


Santander Digital Services
 is a Santander company, based in Madrid with more than 7,000 employees. We are working to move Santander towards a Digital Bank with branches.

Take a look at the job opportunities to work in tech here and Be Tech! with Santander 🚀

Follow us on LinkedIn and Instagram.

Javier Gomez

Javier Gómez

Santander Global T&O

Systems engineer with more than 20 years of experience in different roles as a systems architect, managing Apps & VDIs virtualization solutions and providing end-to-end solutions, as well as managing systems and automating tasks using PowerShell.

I consider myself a restless person and a tireless explorer of the IT universe, who has known how to make his passion his work.

👉 My LinkedIn profile

 

Other posts