Gated Commits with Git

I love the web 🕸
I also write about personal finance in Spanish at https://perrodinero.blog
Search for a command to run...

I love the web 🕸
I also write about personal finance in Spanish at https://perrodinero.blog
No comments yet. Be the first to comment.
I've been wanting to learn Rails since ages ago, but, you know, life was getting in the way (or me, rather). A couple of weeks ago I decided to start a side-project related to another side-project. Sounds like an entry for a GitHub Graveyard, I know....
Sometimes we only need a font for a couple of words, like a logo or slogan. Why do we download the whole font file if we only need a few letters? In this post, I'll show you how you can reduce your font file size by more than 80%. This size reduction...

Queues are a natural phenomenon in everyday life. You queue to buy food, to pay in the supermarket, or to get on a plane. But queues are also used in software to handle heavy processes. A queue can help devs like me and you store a request for later ...

Software development is hard. Time zones are hard. Dealing with time zones in software development? Yeah, harder. Here are 4 places where time zones might differ; and 4 personal bug stories for each case. I'll be referring to the same app for each s...

I started the #100DaysOfCode challenge on March 21st and finished it today, August 7th. FINALLY! 🥳 And yeah, that's way more than 100 days 🙃 For those who don't know, the #100DaysOfCode challenge consists of coding at least one hour every day for t...
A gated commit, also called a pre-tested commit, is an integration pattern in which a commit is not approved until a set of tests are ran against the code being commited. In other words, the commit does not go through if the test suite fails.
Why do you want this? It makes your application more resilient to change since now you are running a set or sub-set of your tests even before that code is available to anyone else.
I am going to show you how to implement a gated commit pattern with Git. In this example, our unit test suite will be the gate to allow our commits to make it to the codebase.
We want our tests to run before a commit goes through. Git allows us to run custom commands just before that event happens thanks to Git hooks. I am not going to go into the details on how they work, but conveniently for us, there is a hook called pre-commit. This hook is executed just before the commit happens. Perfect spot for our test suite to run.
In your Git repo, there is a folder named .git in which the hooks are stored. If you have never modified any hook, your .git directory structure will look like this:

To create our hook, we need to have a file called pre-commit (no extension required) inside our hooks directory. Let's create it. The only thing the file needs to have is the command you use to run your tests. Also, don't forget to make the file executable (chmod +x).
If your application is, let's say, a Ruby application, you probably run your tests using rake. If that's the case, your pre-commit file will look like this:
rake test:units
Or if you are into the JS hype, you can probably have this in your file:
npm tests
Independently of the language/framework you are using, your pre-commit hook needs to have the command to run your unit test suite. And, as long as the code inside the hook returns a zero exit code, the hook will allow the code to be commited. Otherwise, the commit will be rejected.
At this point you can go ahead and make a commit and see how our tests are run (and hopefully pass), thus opening the gate and letting the commit pass uncontested.
In the following example I am using a Grails application, and the pre-commit hook contains the following code:
grails test-app -unit

Success! 🥳
In the case that the test suite fails:

Sad face 🙁
We have just created a Git pre-commit hook that contains specific commands to execute our app's unit test suite. Whenever a commit is issued, our tests run. If tests pass, we have a successful commit, if not, commit is rejected.
You can extend your tests of the pre-commit hook and build something as complex as you need. You can, for example, run a linter tool to make sure style guidelines are being followed. Or take it to the next level and integrate it with your Continuous Integration flow using additional hooks.
Hope this helps you build more resilience into your codebase and, ultimately, deliver more value to your customers in a safe and rapid fashion!