What is pre-commit?

pre-commit is a tool, specifically a package manager. It "manages" custom pre commit plugins or hooks. And what are pre commit plugins? These are basically git hook scripts bundled as an executable which can do various things such as,

So the point is that instead of painstakingly writing and managing git hook scripts, pre-commits are an abstraction over git hooks and make it much easier to use git hook scripts. And its also makes the git hooks shareable.

An interesting thing about pre-commit is that its multi language. What this means is that the pre commit plugins itself can be written in any language and we can run these on our projects written in other languages.

pre-commit manages the installation and execution of any hook written in any language before every commit.

Here are some common exisinting pre-commit hooks.

How to use pre-commit?
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-merge-conflict
      - id: check-yaml

The above configuration tells pre-commit that we would like to use the 4 specified pre commit hooks from the specified repo.

When you run the above command you see something like this

pre-commit installed at .git\hooks\pre-commit

Pre Commit Result

These pre commit hooks can also update the incorrect files if they were programmed to do so.

CAUTION : I did all that and when I do a git commit -m "my message" another version of the committed file shows up in git status. Like there's two. And git push origin master did not push changes to remote. Like it didn't commit. Context: My pre-commits failed. But it modified and fixed the files.

Pre Commit Issue

This is a classic "pre-commit caught an issue, fixed it, but blocked the commit" situation. This happens because the pre-commit hooks "mutate" your staged files (like fixing trailing whitespace or formatting), but Git doesn't automatically pick up those changes for the same commit attempt.

Git Needs You to Re-stage the Fixed Files: Since the files were modified, the index (staging area) no longer matches the working directory, causing the commit to fail.

How to fix this?

Pre-run the Hooks pre-commit run --all-files and then stage, commit and push to remote.


Run pre-commit autoupdate to automatically update the versions of the hooks in your .pre-commit-config.yaml to the latest available releases from each repo.

Pre Commit Issue


There is the below pre-commit hook that prevents direct commits to the main branch

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v5.0.0
  hooks:
  - id: no-commit-to-branch  # prevent direct commits to main branch

pre-commit clean deletes the pre-commit cache in C:\Users\<USER_NAME>\.cache\pre-commit


Another thing to note is that when we run pre-commit run --all-files it runs it only on those files that are staged for commit


Note to self: DO NOT USE isort and reorder-python-imports pre-commits together because they both reorder the imports differently and hence make each other fail.