Introduction
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.
Problem
Standards or conventions can be set, however, without oversight there are always chances of people overlooking them. Remember this famous comic? 😅
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
pre-commit
prepare-commit-msg
commit-msg
post-commit
Server hooks
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
.
1#!/bin/sh
2
3commit_regex='^(\[ISSUE-[0-9]+\] [A-Z][a-zA-Z0-9 -]{1,30})$'
4commit_error='Error! Not as per format -
5 [ISSUE-000] Task description
6'
7if ! grep -qE "$commit_regex" "$1"; then
8 echo "$commit_error" >&2
9 exit 1
10fi
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 -
Success! 👏
Caveats
- Easily disabled by the user!
- They can simply delete the file from the
.git/hook/
directory, or - Use
--no-verify
cli option withgit commit
to bypasses this local hook
- They can simply delete the file from the
- 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. For 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