Pre‑Commit Essentials - A Quick Guide to Setup, Hooks, and Usage
A practical guide to installing pre‑commit, configuring hooks, and using them effectively. Packed with practical examples and ready‑to‑copy snippets, it’s the fastest way to improve code quality with minimal effort.
Overview
-
The 'pre-commit' command can be used to run other programs that will do some checks on a Git repository files, when a 'git commit' command is issued
-
The checks that run during the commit are called 'pre-commit' hooks
-
The commit will actually be performed once all 'pre-commit' hooks run successfully
-
Here is a list of some 'pre-commit' hooks that we can directly use in our projects: hooks list
Installation
Here is a link to the official installation page if needed: install pre-commit
Using pip
Pre-commit is developed with python and can be installed with 'pip'
$ pip install pre-commit
Using .pyz file
We can also directly run the 'pre-commit-#.#.#.pyz' file after getting one from the 'pre-commit' releases page: here
$ python pre-commit-#.#.#.pyz ...
Usage
Hooks configuration file
- 'pre-commit' will look for configurations inside the following file:
.pre-commit-config.yaml - A sample configuration can be generated as follows:
# Generate pre-commit sample configuration file
$ pre-commit sample-config
# Result
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
-
A description of each available configuration file fields can be found here: configuration fields descriptions
-
For a list of supported 'pre-commit' hooks, have a look at this page: hooks list
-
To try a 'pre-commit' repository before actually using it, have a look at this page: hooks dry-run
-
For info about updating the 'pre-commit' configuration (hooks versions) automatically, have a look at hooks versions autoupdate
Running hooks
Here is how you configure 'git' to run the 'pre-commit' hooks on commits:
# Without installing hooks environments.
# Hooks environments will be installed on first run
$ pre-commit install
# With hooks environments installation
$ pre-commit install --install-hooks
Hooks environments contain the required dependencies to run a specific 'pre-commit' hook. To only install hooks environments, run this:
# Only install the necessary for running hooks,
# without telling Git to run pre-commit hooks on commits
$ pre-commit install-hooks
Here is how you run hooks:
# Run hooks on all files
# Hooks environments will be installed if not already done
$ pre-commit run --all-files
Configuration snippets
General purpose
---
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
# See https://github.com/pre-commit/pre-commit-hooks/blob/main/.pre-commit-hooks.yaml for more
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
Secret detection
repos:
# Detects well-known secrets patterns (AWS access key, Github token, etc)
- repo: https://github.com/gitleaks/gitleaks
rev: v8.30.0
hooks:
- id: gitleaks
args: ["protect", "--verbose", "--redact"]
# Detects the presence of private keys
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: detect-private-key
At this time, gitleaks default rules do not detect secrets from fields like 'password', 'token', etc. The following secrets won't be detected for instance:
# File: unencrypted-secrets.yml
password: mysuperpass
token: mytoken
key: mykey
To fix that, we can add custom rules configuration for gitleaks inside the Git repository as follows:
# File: .gitleaks.toml
[[rules]]
id = "generic-secret"
description = "Generic secret assignment"
regex = '''(?i)(password|token|key)\s*[:=]\s*.+'''
With the above custom rules configuration, here is the result:
$ pre-commit install
pre-commit installed at .git/hooks/pre-commit
$ git add unencrypted-secrets.yml
$ git commit -m "commiting a file containing secrets"
Detect hardcoded secrets.................................................Failed
- hook id: gitleaks
- exit code: 1
○
│╲
│ ○
○ ░
░ gitleaks
Finding: REDACTED: mysuperpass
Secret: REDACTED
RuleID: generic-secret
Entropy: 2.750000
File: unencrypted-secrets.yml
Line: 1
Fingerprint: unencrypted-secrets.yml:generic-secret:1
Finding: REDACTED: myREDACTED
Secret: REDACTED
RuleID: generic-secret
Entropy: 2.321928
File: unencrypted-secrets.yml
Line: 2
Fingerprint: unencrypted-secrets.yml:generic-secret:2
Finding: REDACTED: mypreivateREDACTED
Secret: REDACTED
RuleID: generic-secret
Entropy: 1.584962
File: unencrypted-secrets.yml
Line: 3
Fingerprint: unencrypted-secrets.yml:generic-secret:3
7:36PM INF 0 commits scanned.
7:36PM INF scanned ~56 bytes (56 bytes) in 3.72ms
7:36PM WRN leaks found: 3
detect private key.......................................................Passed
Gitlab CI
Automatically generate documentation of Gitlab CI components
repos:
- repo: https://github.com/erNail/labdoc
rev: 3.0.2
hooks:
- id: labdoc-generate
args:
- "--repoUrl=$CI_SERVER_FQDN/my-component-path"
- "--outputFile=./README.md"
Helm
Automatically generate documentation of Helm Charts
repos:
- repo: https://github.com/norwoodj/helm-docs
rev: v1.14.2
hooks:
- id: helm-docs
args:
- --chart-search-root=.
You need to install the 'helm-docs' binary before running this configuration. Installation instructions here: install helm-docs
You can also run it through docker by using 'id: helm-docs-container' instead of 'id: helm-docs' in the above configuration.