Git: Node Pre-commit Hooks

Background

Git hooks allow scripts to be fired off when important events such as committing a change to the repository occur. This guide details how to set up a pre-commit hook for a node application that will execute a testing task that must pass before any new commits are added into the repository.

Why?

Pre-commit hooks allow house-keeping tasks such as code linting and running tests to execute before the commit is added to the repository. If any of these tasks fail then the commit is rejected and not added into the repository. Doing this helps enforce code integrity and prevents simple easy to catch mistakes from creeping in. Of course, any other other kind of tasks could be run like emailing your boss that you’re about to commit, and there are other hooks that can be used for post-commits.

Set up

For this guide, I’ve set up a very simple node command line calculator application that can be cloned and used to follow along with the rest of the article.

The app takes exactly two whole number parameters and sums them together to output the result in the console.

This app has a small test suite that can be run by executing the following command.

Currently, all the tests are passing.

New feature request

Scenario: Your boss comes over to you and says “that calculator app is great… but I urgently need to be able to subtract numbers as well as add. Make it accept an operator as a parameter”.

So the new feature is loosely defined, we could go rushing ahead make changes to the code and commit it immediately. But what about the tests? Well they would be broken because in our haste we forgot to run the tests before committing. Now other team members are upset with us and the build server is sending you emails that you have broken everything. Not good.

If only the tests had been run automatically before the commit was made. And that’s where pre-commit hooks come in.

Adding pre-commit hooks

First set up the git pre-commit hook that will enforce running our tests and making sure they pass before committing to the repository.

The node package “pre-commit” allows the defining of tasks in package.json that will be run before making the commit. If any of these tasks return an error code then the commit will be aborted.

To install:-

Installing pre-commit will add a new task called “pre-commit” into the hidden .git/hooks folder located under the root of the project. It is this script that git will execute before committing to the repository. If the script returns a non-zero value, then the commit will be aborted.

To configure a test task to execute on pre-commit, add the following block into package.json:-

silent reduces the amount of noise that pre-commit logs out to the terminal.

run takes an array of npm tasks to execute. These tasks are defined within the “scripts” block in the package.json file.

By default, npm test will be called if no run tasks are defined, but chances are that more tasks such as linting will be added the project so I prefer explicitly defining this upfront. Read the pre-commit documentation for more information.

That’s it. Now whenever anybody commits changes to the repository, the tests will execute. If the tests return a non-zero result, the commit will be abandoned with an error message.

Adding the feature

To add the subtract feature to the code, I’ve created a gist that you can copy the changes from. Replacing the contents of calc.js with this gist will add the subtract function into the program.

Now the user needs to enter 3 arguments rather than two to operate this simple app.

Giff diff report showing the changes made to calc.js to add the subtract feature
Giff diff report showing the changes made to calc.js to add the subtract feature

In the terminal, the user can now execute the following command to add or subtract two numbers:-

Terminal output showing program running addition and subtraction operations.
Terminal output shows that the calc app now can add and subtract numbers together

Great! The changes work, feature complete. Time to commit.

Git prehook commit failure message
Terminal output showing the broken test caused by adding the new feature in.

The commit was rejected because the tests are no longer passing. Excellent, the tests were automatically run and have stopped the feature from accidentally being committed to the code base.

Now all that remains to be done is to fix the existing tests and add a new test for the new subtract feature, then commit. Check out the subtract-feature branch on the repo for the solution.

Git pre hook success message
Terminal output showing that are tests are now passing before making the commit

Further reading

You can find more information about git hooks on https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.