Git Hooks: pre-commit Hook for ESLint using Python

CodeStax.Ai
6 min readDec 13, 2022

--

Introduction

Git, one of the most widely used Version Control System(VCS), allows multiple developers to coordinate and contribute to a single project. It allows developers to customize git actions to meet their own organizational coding standards or quality requirements. Git Hooks are one of the customizations offered by git. They can also be used to build a CI/CD pipeline for your projects.

What are Git Hooks?

Git hooks are just a bunch of scripts that run automatically when a certain event occurs in your repository. There are two main types of hooks, namely, Client-side Hooks and Server-side Hooks. Simply put, Client-side hooks are scripts that run on your local machine whereas the Server-side hooks are scripts that execute on git server.

Installing Hooks

Hooks are located in the ‘.git/hooksdirectory of a git repository. By default, git populates this directory with a bunch of .sample files, which are actually shell scripts.

To install a certain hook, remove its ‘.sample’ extension. There are default scripts provided for each script by git but you can write your own scripts in your preferred scripting language as per your standards.

Pre-commit Hook

In this article, we’ll focus only on pre-commit hook. Git’s pre-commit hook executes every time you run ‘git commit’ before git generates a commit object. This hook can be used for static analysis of code being committed, linting, spell-checks, code-styles etc. It is used to make sure you don’t unexpectedly push unformatted code or violate organizational coding standards.

Implementation

In this article, we’ll implement git’s pre-commit hook for ESLint’ing our code to demonstrate the use of git hooks.

ESLint is a static code analysis tool for identifying problematic patterns found in JavaScript code, created by ‘Nicholas C. Zakas’. Rules in ESLint are configurable, and customized rules can be defined and loaded. ESLint covers both code quality and coding style issues.

1. Setup a Project :

Lets create a sample nodeJS project using simple steps.

  • Create a new directory for the project and navigate to that folder in command prompt or terminal.
  • Execute ‘npm init’ and fill in the options or press enter/return to choose default values.
Create a project using npm
  • Initialize git repository using ‘git init’ in Git Bash.
Initialize Git Repository
  • Create an app.js file in root directory and add some sample code.
// app.js
const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log('Listening on port 3001');
})

2. Install and Initialize the ESLint :

  • You can install ESLint using npm by executing the command:
npm install -g eslint
  • Initialize ESLint.

For a detailed explanation of coding standards and ESLint, you can visit this article.

  • I’ve added some rules to .eslintrc.json file but this is optional while using style guide like Airbnb.
{
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"extends": "airbnb-base",
"overrides": [
],
"parserOptions": {
"ecmaVersion": "latest"
},
"rules": {
"no-console" : 0,
"camelcase": 1,
"eqeqeq" : 0,
"import/newline-after-import": "off",
"linebreak-style": 0
}
}

3. Install Pre-commit Hook

  • You’ll find pre-commit.sample file in ‘.git/hooks’ directory of your project.
  • In case you don’t see .git directory in your project folder, you might have to unhide it. If you are using VS Code as your text editor, you can unhide directory as follows :
    File -> Preferences -> Settings -> Text Editor -> Files -> Delete ‘**/.git’ from Exclude section.
  • Let’s install the hook by removing ‘.sample’ extension in ‘.git/hooks’.
  • You’ll see a default shell script on opening the pre-commit file. Let’s write some Python code to execute ESLint on files that are staged to commit.

pre-commit file :

#!/usr/bin/env python
import sys, os
if __name__ == '__main__':

display_errors = []

# Get all the files that are staged to commit.
# diff-filter: Used to filter files from the staged commit.
# A = Added files; C = Copied files; M = Modified files
staged_files = os.popen('git diff --cached --name-only --diff-filter=ACM')
# Loop through the files.
for file in staged_files.read().splitlines():
# To check for ESLint errors only in .js files.
# Remember if you push nodemodules to your repository you should add another condition:
# not file.startswith('node_modules/')
if file.endswith('.js'):
# Execute eslint for each file.
eslint_exec_result = os.popen('eslint '+ file)
# Add all the errors to display_errors array.
for error in eslint_exec_result.readlines():
display_errors.append(error)

if display_errors:
# Print all the errors
for error in display_errors:
print(error)
# Abort the commit(By returning a non-zero value)
sys.exit(1)
# Continue to commit.
sys.exit(0)

4. Commit Changes :

  • Let’s now try to add and commit the changes we’ve made so far.
  • The commit is aborted because we have some ESLint errors in our javascript files.
  • Let’s fix them and try to commit again.
// app.js
const express = require('express');
const app = express();

app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Listening on port 3000');
});
  • Now the commit is successful, which means we’ve passed the ESLint check.

Scope of Git Hooks

The .git/hooks directory cannot be cloned along with other project files by using ‘git clone’. Hence, how to share these hooks among a team of remote developers is question that exists. There are certain ways to configure them. A simple solution is to store them inside another project directory(above the ‘.git’ directory) and push them to git. Any other remote developer of same project can install a hook simply by copying from this new directory and pasting them into respective hooks of .git/hooks directory. This way, all the developers can follow these scripts and the scripts themselves will be version-controlled.

Conclusion

Using Git Hooks is a simple and easy way to alter git’s internal behavior such that it meets the expectations of your project. These hooks can help act as checkpoints to maintain code quality. Writing effective hooks is not easy, but mastering it will save you loads of manual work.

About the Author

Vinuthna is a Software Development Engineer at CodeStax.Ai with 1.4 years of experience in IT industry. She loves full stack development the same way she loves chocolates.

About CodeStax.Ai

At CodeStax.Ai, we stand at the nexus of innovation and enterprise solutions, offering technology partnerships that empower businesses to drive efficiency, innovation, and growth, harnessing the transformative power of no-code platforms and advanced AI integrations.

But the real magic? It’s our tech tribe behind the scenes. If you’ve got a knack for innovation and a passion for redefining the norm, we’ve got the perfect tech playground for you. CodeStax.Ai offers more than a job — it’s a journey into the very heart of what’s next. Join us, and be part of the revolution that’s redefining the enterprise tech landscape.

--

--

CodeStax.Ai
CodeStax.Ai

Written by CodeStax.Ai

Tech tales from our powerhouse Software Engineering team!

No responses yet