Automate Python Code Formatting with Pre-commit Hooks
Learn how to set up pre-commit hooks to automatically format and lint Python code before every commit, saving your team hours of review time and ensuring consistent style across your project.
Here is the article based on your instructions.
Automate Python Code Formatting with Pre-commit Hooks
Let’s be honest: nobody enjoys reviewing code that has messy indentation, trailing whitespace, and imports all over the place. It’s distracting, and it slows down the whole team.
But here’s the real kicker: most developers don’t fix formatting issues because they forget to run the linter before committing. It’s not that they’re lazy—it’s just human.
That’s where pre-commit hooks come in.
Think of them as a bouncer at a club. Before your code gets into the repository (the club), the bouncer checks if it's dressed properly: well-formatted, no obvious errors, and proper imports. If it passes, great, it gets in. If not, you fix it right there.
At PythonSkillset, we see teams waste hours in pull request comments arguing about spaces versus tabs. Pre-commit hooks kill that drama entirely.
What Exactly Is a Pre-commit Hook?
A pre-commit hook is a script that runs automatically every time you type git commit. It sits between your staging area and the commit. If the script passes, the commit goes through. If it fails, the commit is blocked.
You can set it up to run tools like: - Black for code formatting - Flake8 or Ruff for linting - isort for sorting imports - check-yaml to validate YAML files
The best part? You set it up once, and then it works for every commit you make. No thinking required.
Setting It Up in 4 Steps
Let’s walk through a real example. I’ll use a Python project called pythonskillset_blog (fictional, but works the same).
Step 1: Install pre-commit
Open your terminal and run:
pip install pre-commit
Step 2: Create a configuration file
In the root of your project, create a file named .pre-commit-config.yaml. This is where you define the hooks.
Here’s a minimal but effective config for Python projects:
repos:
- repo: https://github.com/psf/black
rev: 24.4.2
hooks:
- id: black
language_version: python3.12
- repo: https://github.com/PyCQA/flake8
rev: 7.1.0
hooks:
- id: flake8
- repo: https://github.com/PyCQA/isort
rev: 5.13.2
hooks:
- id: isort
Step 3: Install the hooks into your Git repository
Run:
pre-commit install
This tells Git to run the hooks before every commit.
Step 4: Test it
Make a small change in your code — add a bad indentation or an unused import — and try committing.
git add .
git commit -m "test hook"
You’ll see something like this:
Black....................................................................Failed
- fix by running `black .`
Flake8...................................................................Failed
isort....................................................................Failed
The commit is stopped. You fix the issues, re-stage, and commit again. This time it passes.
Pro Tip: Run on All Files Once
If you’re retrofitting an existing project with hooks, you can run the hooks on all files without committing.
pre-commit run --all-files
That’s a quick way to clean up an entire codebase in one shot.
Why You Should Bother
Some developers resist automation like this. They think: "I can format my own code, thank you."
But here’s the thing: you’re not doing it just for yourself. You’re doing it for everyone who will touch your code later.
When every file in your repository follows the same style, reading code becomes faster. Code reviews become about logic, not formatting. And new team members can jump in without learning a custom style guide.
For PythonSkillset readers, this is not just a nice-to-have—it’s a productivity multiplier.
What If I Need to Skip a Hook Sometimes?
There are rare cases where you need to commit something that breaks a rule intentionally (like a temporary debug print). You can skip hooks by using --no-verify:
git commit -m "urgent fix" --no-verify
But use this sparingly. It’s like the emergency exit — don’t make it your everyday door.
Final Thought
Setting up pre-commit hooks takes less than 10 minutes. In return, you save hours of manual formatting and reduce friction in your team.
It’s one of those small automation steps that pays for itself on day one.
Next time you start a Python project, drop a .pre-commit-config.yaml in the root. Your future self (and your teammates) will thank you.
Comments
Questions, corrections, and tips stay visible for everyone reading this page.
Join the discussion
No comments yet
Be the first to leave a note — it helps the next reader.