Pre-Commit Hook, it’ll Git ya!

So following up on my previous blog about using a linter such as ESLint to help enforce consistency in styling and guidelines for JS, this blog will go into combining git hooks to really enforce those guidelines laid out by the development team.

Git hooks are scripts that run automatically when a specific action is triggered from a Git repository.  They allow customizing actions within your Git workflow when events such as committing, pushing, or receiving are performed.  Git hooks are a built-in feature, and don’t require any additional download to use.  Also, the Git hooks run locally so they will only affect your local repository.

Hooks reside in the .git/hooks directory of every Git repository and by default, Git has sample script files which are created when you first initialize a repository, as seen below.

Screenshot_120117_033209_PM.jpg

They all have the .sample file extension, therefore if you wanted to use them, just remove the .sample in the filename and Git will automatically execute the script depending on the action triggered.  You can also create our own scripts but note that the hooks have to be executed and so certain permissions may need to be setup for those custom files.

The client-side hooks are: pre-commit, prepare-commit-msg, commit-msg, post-commit, post-checkout, and pre-rebase.

The server-side hooks are: pre-receive, update, and post-receive.

We will only be dealing with the pre-commit client-side hook, which is executed every time a ‘git commit’ command is ran but before the actual commit is performed.  This hook is useful when you want to run automated tests to ensure your tests are not failing, or for linting code (which is what we are using) to ensure your code meets the specific guidelines set in place.

Please feel free to read up on the other Git hook types and when you could use them:

To assist in automatically linting JS files when performing a Git commit, we install the two npm packages below because they make the process much more easier to work with:

  • husky (Git hooks made easy): Because the hook scripts are located under the .git/hooks directory, it is not easy to share the files across a development team.  This is where Husky comes in, it allows using predefined script tags like:

    “scripts”: {
    “precommit”: “echo Perform some action here”
    }

    within the package.json file to be ran as a git hook.

  • lint-staged: Allows running an npm script while specifying the directory for staged files.  This helps in that we do not lint every JS file in the project when we are ready to commit our code, but only the files which have been staged.

Below is a sample of the package.json file which has a script for both the “precommit” and “lint-staged” command:

“scripts”: {
“precommit”: “lint-staged”
},
“lint-staged”: {
“*.js”: “eslint ./assets/ –config .eslintrc.json”
}

Here is a sample test.js file that we will use (somewhat similar file from the previous blog I wrote about ESLint):

Screenshot_120117_061505_PM.jpg

After staging and trying to commit this file in SourceTree, you will notice that the pre-commit hook is automatically ran and displays the errors based on the ESLint configuration.  As you can see, we are not allowed to commit our code because of the errors found when linting.  Nice indeed! :

Screenshot_120117_061809_PM.jpg

Running the git commit in the command window will result in the same errors as shown below:

Screenshot_120117_061910_PM.jpg

We can manually update the test.js file, but instead lets run the eslint script using the “–fix” option to automatically fix any syntax errors:

“eslint ./assets/ –fix –config .eslintrc.json”

Let’s try to commit again and see what happens:

Screenshot_120117_062104_PM.jpg

BOOM!  As you can see ESLint was able to automatically fix our trivial syntax errors and pass our rules thus allowing us to finally commit our work.  Woo Hoo!

NOTE: You can bypass the pre-commit hook in case there is ever a need to, by using the “–no-verify” flag on your commit command:

git commit -m “bypass git prehook” –no-verify

In conclusion, using Git hooks is always a good thing, especially when combining the pre-commit hook and a linter to keep ugly JS code from being committed into the repository in the first place.  Git hooks are sweet to use, just as sweet as Kareem’s epic hooks:

 

Kareem hookshot.gif

 

Leave a comment