Git Hooks

Background

Git is a very powerful tool with a lot of hidden features. Some of those features are left to the more experienced git users. One of those features is the usage the usage of hooks.

Hooks are, as their name suggest, a little piece of code that runs before or after some git action executed. Hooks default path is under your project directory at .git/hooks/<hook_name>.

You can read more about the hooks at the following web page

For example, I enjoy using a hook before each commit to ensure I have no break points in my code. This allows me from accidentally publishing code that may contain something I forgot to remove. Other people may enjoy running a test suite before committing code, running migrations after a successful pull, or anything else you can imagine.

While I am far from being a git expert, I would like to share with you some of the findings I have with hooks.

Issue

An issue I found to be particularly annoying is that hooks are project specific. When creating a new project, you would then have to manually copy the hooks from a similar project. Even more annoying than that, when updating a hook somewhere, one would have to go in every project using that hook and apply the same change to each file. This goes against the DRY (Don’t Repeat Yourself) principle (though this is across projects so may not apply here).

Solution

SuperHooks is a tool I came up with while using multiple repository and git hooks. The motivation to write this came from the absence of support and inspiration of an existing tool git-hooks as well as its lack of maintenance. Also, being myself more of a Rubyist, I wanted to work my skills on a tool that would be tested and written entirely in ruby and easy for someone to contribute to.

The concept is quite simple. The hook itself becomes a wrapper around something more complex. Every hook is instantiated with some similar code. When the code is executed, it knows about what hook was invoked and finds directories you have identified as containing that hook. All executables in that hook directory are then found and executed. In the case of a validation for example, all hooks would have to exit successfully in order for the wrapper to exit with a graceful exit code.

The advantage of using such a tool is multiple. Not only do you not have to manage each project separately by having the same executable run for multiple project, you also benefit from the single responsibility principle. You now have different scripts checking different things as isolated pieces of code.