A consistent convention, whether it is for naming branches or adding commit messages is absolutely essential for a team. Following a common theme or standard ensures the readability and maintainability of the project. It also makes the lives of people who will come after you a lot easier.

The Problem

Standards or conventions can be set, however, without oversight there are always chances of people overlooking them.

The Solution

Git provides scripts out of the box, which run on certain events. These can be run locally or on the git server. Having these hooks locally makes them easier to edit or implement, but they are easy to bypass.

Local hooks are - pre-commit, prepare-commit-msg, commit-msg, post-commit

Server hooks are - pre-receive, update, post-receive

To establish an oversight mechanism for commit messages, use the commit_msg hook. It runs after a local commit, and fails the commit if the script exits with a non-zero code.

Local hooks can only serve as a guidance and should not be relied upon for enforcements. Server hooks are a better choice for enforcing rules. Local hooks reside in the folder .git/hooks/ and are not checked into source control.

Let’s assume we want every team member to add commit messages in the following format -

[ISSUE-000] Short description in 50 chars or less 

To nudge the team to adhere to this standard, distribute the commit-msg file in a separate directory in your source control, like hooks.

#!/bin/sh

commit_regex='^(\[ISSUE-[0-9]+\] [A-Z][a-zA-Z0-9 -]{1,30})$'
commit_error='Error! Not as per format -
        [ISSUE-000] Task description
'

if ! grep -qE "$commit_regex" "$1"; then
    echo "$commit_error" >&2
    exit 1
fi

Add appropriate instructions in the README.md of the project on how to enable it. High level steps will be -

  • Add a symlink or simply copy the files from hooks directory to .git/hooks/.
  • Make sure the files under .git/hooks/ are set to executable.

Test by adding a random commit you expect to fail - image

Success! 👏

Caveats

  • Easily disabled by the user - they can simply delete the file from the .git/hook/ directory.
  • --no-verify cli option bypasses all checks.
  • Use server side hooks to enforce compliance or other checks.
  • Local hooks work with Gitbash for Windows, so no extra config is required for Windows.

Conclusion

Git local hooks provide an excellent option to automatically execute scripts on certain events. Example, run lint after checkout, or do a code scan before commit, etc. Local hooks can be useful to setup oversight to make sure you don’t stray from the set standards or conventions. They, however, are not for setting up guardrails or enforcement as they reside on each user’s system and are completely under their control.

Adding a check for commit message is only a small part of the overall functionality that Git hooks provide. Check the documentation to know more and explore what else can they do.

Hope this post proves useful! 👍

Note:  Code mentioned above is here 

References (1)

  1. Customizing Git Git Hooks