Pros and cons of pre-commiter framework and my verdict (Ft. pre-commit)
Motivation
Before uploading or committing with git commit
, it is essential to locally
check that the modified code adheres to the principles and styling guide
provided by the GitHub repository maintainer.
Here, pre-commit
is a simple Python library that checks formatting and linting
so that contributors must follow the shared practices to maintain code quality
agreed upon by members.
Installation
When you run git init
, it generates files containing .git/hooks/pre-commit
.
This folder contains .sh
scripts that allow you to execute a set of tasks to
check for issues, like running tests for formatting and linting the code before
git commit
.
Of course, pre-commit
will automate the above process.
Install via:
$ pre-commit install
pre-commit installed at .git/hooks/pre-commit
How to use
Create a file named .pre-commit-config.yaml
at the project level. Here, I want
to add a few hooks for checking yaml and running ruff
.
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.5.0
hooks:
# Run the linter.
- id: ruff
args: [--fix]
# Run the formatter.
- id: ruff-format
Once the config file is in place, make a regular commit:
git add .
git commit -m "Use a numpy version of 1.23"
pre-commit
tests locally and either rejects or approves your commit as shown
below and modifies the files:
[INFO] This may take a few minutes...
Check Yaml...............................................................Passed
Fix End of Files.........................................................Failed
- hook id: end-of-file-fixer
- exit code: 1
- files were modified by this hook
Fixing .pre-commit-config.yaml
Fixing [README.md](http://readme.md/)
Once they are fixed automatically by pre-commit
, run the commit command again:
git commit -m "Use a numpy version of 1.23"
Debates on usage
Against
- Linting and formatting checks occur in CI, no need for duplication.
- Developers can format freely but must adhere to project standards before pushing to the branch.
- Precommit hooks can interrupt workflow.
- They often get disabled until PR merge due to their annoyance.
- When developers feel impeded, they tend to increase the size of their commits.
For
- It prevents contributors from submitting ill-formatted code, saving time before CI checks.
My verdict
As of now, I am overall optimistic about using pre-commit
. Here is my
justification:
In my workflow, I use nodemon
to run mypy
, ruff
, and pytest
each time I
modify a file. However, not all users adopt my workflow. It is likely that I
will have no problem with pre-commit
hooks since I regularly check them.
But the issue becomes more significant with open-source project contributions. I want the codebase to remain consistent and adhere to the standard. While GitHub Actions can perform the exact task, it requires 10-15 minutes. I want contributors (mostly without formal CS background) to feel confident that when the code passes at the commit level, it can be considered mergeable.
As long as pre-commit
takes within 10 seconds or so, I am optimistic.
References
- https://www.reddit.com/r/ExperiencedDevs/comments/144fcqo/what_are_your_precommit_hooks/
- https://www.reddit.com/r/git/comments/16ke0xa/arguments_for_and_against_precommit_hooks/
- https://www.thoughtworks.com/en-us/insights/blog/pre-commit-don-t-git-hooked
- https://pre-commit.com/
- https://medium.com/@josephbkahn/pre-commit-hooks-the-good-the-bad-the-ugly-5c5ff7a0d0d8