pre-commit - framework for managing git hooks
Beefy IDE helps us a lot with producing good quality code by validating formatting, running some checking scripts, and so on. This kind of help is limited to how well you configure your IDE, but how can we propagate those checks for everyone or create our own custom checks with a few lines of bash script or even include it to our CI/CD systems? Here comes the pre-commit itself described as: a framework for managing and maintaining multi-language pre-commit hooks
. Using pre-commit
you can prepare your own hooks (ie. bash script), expose it as git repository and refer to it in your projects at different git hook levels. The big advantage of pre-commit
is a huge hooks repository for most use cases and you can run pre-commit
without waiting for git hook. Documentation is pretty extensive so I won’t gonna copy/paste, but rather concentrate on a sample use-case. If you are using GitHub, when you first push your changes you will get a help URL to create PR, but every next push you won’t get the URL to already created PR. So let’s prepare git hooks at pre-push level to get URL of the existing PR.
The first prepare git repository for our new pre-commit hook, the content look like this:
❯ ls -la
drwxr-xr-x - wit 10 Apr 09:34 .git
.rw-r--r-- 154 wit 10 Apr 08:42 .pre-commit-hooks.yaml
drwxr-xr-x - wit 10 Apr 08:26 hooks
❯ cat .pre-commit-hooks.yaml
- id: gh-pr-url
name: gh-pr-url
description: Get github PR url
entry: hooks/gh-pr-url.sh
language: script
require_serial: true
stages: [push]
❯ cat hooks/gh-pr-url.sh
#!/usr/bin/env bash
set -e
if ! command -v jq >/dev/null; then
echo "no jq installed"
exit 0
fi
if ! command -v gh >/dev/null; then
echo "no github cli installed"
exit 0
fi
if git remote -v | grep -q "github.com"; then
PAGER="" gh pr view --json url | jq -r .url || exit 0
else
echo "not github repo"
fi
I choose Github CLI to view PR from the current working directory git repository and parse it using jq. Now we can refer to this hook in our project:
❯ cat .pre-commit-config.yaml
repos:
- hooks:
- id: gh-pr-url
stages: [push]
verbose: true
repo: <url>
rev: <revision_or_tag>
then check it right beforing installing git hook:
❯ pre-commit run -v --hook-stage push -a
gh-pr-url................................................................Passed
- hook id: gh-pr-url
- duration: 0.01s
<PR_url>
if it’s working as expected, we can install it:
❯ pre-commit install --install-hooks -t pre-push
pre-commit installed at .git/hooks/pre-push
and check it in practice:
❯ git commit -m 'test'
[master 9ab3954] test
1 file changed, 1 insertion(+)
❯ git push origin master
gh-pr-url................................................................Passed
- hook id: gh-pr-url
- duration: 0.52s
<PR_url>
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 299 bytes | 299.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
...
powered by Hugo and Noteworthy theme