Elena' s AI Blog

Linters and Git Pre-commit

11 Sep 2022 (updated: 06 Aug 2026) / 9 minutes to read

Elena Daehnhardt


Flux: A developer's hands at a keyboard with a terminal window showing a Git commit being checked, a red X turning to a gre...


TL;DR:
  • Setting up Git pre-commit hooks with linters: automatically checking Python code style (PEP 8) before committing files to maintain coding standards and code quality.

Previous: Part 19 — GitHub Codespaces

Next: Part 21 — The SSH host key mystery

Automating PEP 8 Style Checks with Git Pre-commit Hooks

A Git pre-commit hook is a script that runs automatically before each commit and can block the commit if a check fails. This post sets up pre-commit hooks with Python linters to enforce PEP 8 code style automatically before files are committed.

Coding gets hectic, and style is usually the first thing I drop when I’m racing to finish something. That’s a mistake: PEP 8 is the official Python style guide, and it sets out rules for naming, commenting, indentation, and whitespace. Following it produces code that’s easy to read and reuse — which matters a lot more once someone else has to work in your codebase.

PEP 8 is a standard, not an enforcement mechanism, so you need tooling to check and fix violations automatically. Flake8 is one such tool (alongside others such as Pylint and PyLama) that inspects code for PEP 8 compliance errors — see Flake8: Your Tool For Style Guide Enforcement. Tools like this are called linters. In this post, I use Git hooks and pre-commit for a simple setup that checks Python code before you commit files into the repository.

Python Linters: Flake8 for PEP 8 Compliance

A linter is a static-analysis tool that checks source code for syntax errors and style violations without executing it. Linters ensure code quality in the following aspects:

  1. ensure correct code formatting and style;
  2. minimise syntax errors;
  3. help in code reviews;
  4. save development time.

Flake8 is a Python linter that is easy to install with pip. Pip is the standard package manager for Python; if you need guidance on installing it, read the article at realpython.com. Since you are reading this post, you most likely already have pip on your system.

# define which Python version you want to install flake8 for
python<version> -m pip install flake8

To use Flake8, run it on a specific file or directory.

# Run Flake8 on repo directory
flake8 path/repo
# Run Flake8 on the file main.py
flake8 path/repo/main.py

Code Formatters: Black for Automatic PEP 8 Formatting

Black is an opinionated Python code formatter that rewrites source files to a deterministic PEP 8-compliant style. You can use Black alone or together with Flake8. Per the official Black installation docs, Black requires Python 3.10+ to run and is installed with pip.

pip install black

The usage is similar to Flake8; just feed in the project directory or file.

black <file_or_directory>

Black reformats Python files following PEP 8 guidelines, while Flake8 checks for syntax and style errors. Using them together is good practice, and they work well in tandem. Refer to the docs “Using Black with other tools” for more details on Black’s compatibility with Flake8 and other linters.

Git Hooks and the pre-commit Framework

pre-commit is a framework for managing and running Git hooks that checks and reformats code before it is committed to the repository. Once installed, it runs your configured checks automatically on every git commit. See the official pre-commit documentation for the full hook catalogue.

Installing pre-commit in a Git Repository

To install pre-commit in your Git repository folder, run the following commands.

# Install pre-commit
pip install pre-commit
# Install git hooks in your .git/ directory
pre-commit install

Configuring .pre-commit-config.yaml for Black and Flake8

To configure the hooks you want to include, define a .pre-commit-config.yaml file in the project repository. Here’s a config for Black and Flake8, following the current hook syntax from Black’s own docs and Flake8’s docs:

repos:
  - repo: https://github.com/psf/black-pre-commit-mirror
    rev: 26.5.1
    hooks:
      - id: black
        language_version: python3.11
  - repo: https://github.com/pycqa/flake8
    rev: 7.3.0
    hooks:
      - id: flake8

Black’s own docs recommend the black-pre-commit-mirror repo rather than psf/black directly, since it lets pre-commit use a faster mypyc-compiled build. Pin rev to whatever the latest release tag is when you set this up — both projects tag new versions regularly, so treat the versions above as a snapshot, not a permanent value.

When you install pre-commit, it creates a Git hook (a shell script) in the hidden .git/hooks directory of your repository. These scripts automate your development process. As you can see below, some Git hook scripts (files with the .sample extension) are already installed in a fresh Git repository.

ls .git/hooks
Git hook files

To read the Git manual about githooks, run:

man githooks

Running pre-commit Hooks on Commit and on All Files

The pre-commit hook automatically runs code style and formatting checks when you commit, and the commit is blocked if a check fails. You can also run pre-commit across every file in the repository on demand, not just the staged ones.

pre-commit run --all-files

Sometimes there’s an issue you can’t fix immediately, but you still need to get a commit through. The --no-verify flag on git commit bypasses the pre-commit hook entirely, so use it sparingly.

git commit -am "commit message" --no-verify

Resolving “command not found: pre-commit”

If pre-commit install returns command not found: pre-commit, the package is not on your PATH. Cause: pre-commit was installed into a different Python environment or user site directory. Fix it by reinstalling into the active environment and verifying the executable:

pip install --user pre-commit
python -m pre_commit --version

Final Thoughts: Git Pre-commit Workflow for PEP 8

A Git pre-commit hook gives you a simple, automated Python development cycle: Flake8 lints for PEP 8 and syntax errors, Black reformats files, and the commit is blocked until checks pass. I’ve shown you how to install pre-commit in a Git repository and configure it to run Flake8 and Black on every commit — set it up once, and you stop thinking about style altogether.

Git Pre-commit FAQ

How do I install pre-commit in a Git repository?

Run pip install pre-commit to install the package, then pre-commit install inside the repository to register the Git hook in .git/hooks/pre-commit. The hook then runs automatically on every git commit.

How do I run pre-commit hooks on all files, not just staged ones?

Run pre-commit run --all-files. By default the hooks only check staged files; this command applies every configured hook (Black, Flake8) across the whole repository.

How do I commit when a pre-commit hook fails?

Use git commit -am "message" --no-verify. The --no-verify flag bypasses the pre-commit hook so the commit goes through, useful when a style issue cannot be fixed immediately. Use it sparingly.

What is the difference between Black and Flake8?

Black is an autoformatter that rewrites code to a consistent PEP 8 style, while Flake8 is a linter that reports PEP 8 violations and syntax errors without changing files. They are commonly used together in one .pre-commit-config.yaml.

References

  1. PEP 8 – Style Guide for Python Code
  2. Black (PyPI)
  3. Black: Getting Started (installation and Python version requirement)
  4. Black: Version control integration (pre-commit config)
  5. Using Black with other tools
  6. Flake8: Your Tool For Style Guide Enforcement
  7. Flake8: Using Version Control Hooks
  8. pre-commit: A framework for managing and maintaining multi-language pre-commit hooks
  9. Git hooks documentation
  10. git-commit: the --no-verify option
  11. realpython.com: What Is Pip?

Did you like this post? Please let me know if you have any comments or suggestions.

Posts about development tools and Python coding

desktop bg dark

About Elena

Elena, a PhD in Computer Science, simplifies AI concepts and helps you use machine learning.

Citation
Elena Daehnhardt. (2022) 'Linters and Git Pre-commit', daehnhardt.com, 11 September 2022. Available at: https://daehnhardt.com/blog/2022/09/11/edaehn-git-pre-commit/
All Posts