Overview of Git Hooks
While working in different development projects, private and business, I’ve noticed that sometimes you simply do not spend enough attention on your commit or push to the repository and suddenly the build is failing or your source code is simply full or ToDo notes and other stuff you usually don’t want to keep as it only creates technical debt that requires more time to clean later than it would if you’d have done it now.
I also thought that while spending more attention obviously helps to prevent this, it won’t help all the time. After all we are all just humans and we do make mistakes and forget things. So what I wanted is some technical rule or script to run before I either commit or even push my code to ensure I’ve double-checked my code.
I thought that Git would probably have something like lifecycle hooks that a developer can hook into. After a little research I’ve found some information about it in the offical documentation and also some blog posts, but I was surprised how few that information was. This is why I am writing this post now.
Git dummy hooks
Git offers to called hooks to execute specific commands just before an action like commit. All available hooks can be found in the official Git documentation. Inside the .git folder of your projects there is another /hooks folder with the following list of files:
These are all the hooks that Git support. All files are suffixed with .sample telling Git not to execute those as they are dummies that were created automatically. This is where we can insert our own custom logic!
There are lots of use cases for these commit hooks: check code styling (as seen in the example below), run tests, add another layer of logging/documentation. Find more ideas here.
Pre-commit to style-check your code
In Angular projects a linter is used to style-check the code, which complains if any errors appear. Often this linter is also part of the build-pipeline, making the build fail even if you only forgot to put a semicolon at the end of the line (feels pretty Java to me). The example below modifies the pre-commit sample Git provided in order to execute the linter before the actual commit happens:
In line 3 I simply set a name to prepend before each echo command. In line 10 I then execute the typescript linter to check my code. The results are checked in line 12: if the previous command was successful, it will return a status of 0. If it failed, it will return 1. Depending on the exit status, Git will either abort the commit or finish it. Finally, the file ending .sample must be removed from the script in order to tell Git to actually execute this hook.
Now the following screenshot shows a code line which exceeds the configured maximum number of characters per line. You can have a visual helper in Visual Studio Code called editor ruler, which is visible in the screenshot as well).
The linter will complain here as one of the rules is being violated.
Trying to commit any changes now will run the pre-commit hook which in turn executes the linter. The output tab of Visual Vtudio Code logs Git commands as well. There we can clearly see our [Pre-commit] snipped as well as the original linter output with the errors:
The commit was aborted due to the exit status of 1 (error), which gives you the time to clean up and try again ;-)
Git hooks offer an adapter for custom scripts to be executed before or after any of the Git actions like commit or push. Developers can write scrips to execute all kinds of commands and decide on the exit status of these to proceed with the Git action or the abort it. This comes in handy to keep source code repositories clean off ToDo marks or linting complaints for example. I hope this helped and was something new for some of you and I’d love to here your use cases and whether this was actually new to you!