Git hooks with pre-commit
I was listening to the episode Get inside the .git folder on the podcast Talk Python To Me and learned about pre-commit hooks. Git hooks are commonly used with linters and formatters.
In this post, we’ll create a hook with pre-commit that runs prior to committing using the formatter black and the linter flake8. The goal is to keep code up to standards and as readable as possible. But first:
What are hooks?
You can find the hooks folder within repo/.git/hooks
This directory contains shell scripts that are invoked after the Git commands they are named after. For example, after you run a commit, Git will try to execute the post-commit script, if it has executable permissions.
Here’s a full list of hooks available:
- applypatch-msg
- pre-applypatch
- post-applypatch
- pre-commit
- prepare-commit-msg
- commit-msg
- post-commit
- pre-rebase
- post-checkout
- post-merge
- pre-receive
- update
- post-receive
- post-update
- pre-auto-gc
- post-rewrite
- pre-push
How to create a hook without pre-commit
$ cd your_repo/
$ vim repo/.git/hooks/pre-commit
add the following:
#!/bin/bash
echo Luke makes the best pre-commit hooks
echo PWD is $PWD
Now each time you commit, this will run before the commit finishes.
pre-commit creates these scripts automatically
Pre-commit generates these scripts for you from a .yaml
file then stores the generated script in the appropriate place within repo/.git/hooks/<hook_type>
. Here’s an example of the script that is generated by pre-commit after following the instructions below.
How to configure pre-commit with black and flake8
$ cd your_repo/
$ python3 -m venv env
$ source env/bin/activate
$ pip install pre-commit
optional: $ pip freeze > requirements.txt
to update your requirements
Create the pre-commit .yaml
file in your repository
$ vim .pre-commit-config.yaml
Have pre-commit generate the script from your .yaml
file and output it into repo/.git/hooks
then format and lint all existing files in your repository
$ pre-commit install
$ pre-commit run -all
From now on, when you commit, this hook will run then format and lint all your modified files in this repository.