To set up pre-commit security checks, install the pre-commit framework, add a .pre-commit-config.yaml with pinned hook revisions, run pre-commit install so the hook fires on every commit, run it once across all files, and repeat the same run in CI because local hooks can be skipped.
Key takeaways
- pre-commit is a framework that runs hooks you list in one YAML file.
- Pin every hook to an immutable tag or commit SHA, never a branch.
- Run against all files when you add a hook, since a normal commit checks only changed files.
- Local hooks are advisory. CI is the enforcement point.
- Catch secrets before the commit, because removing them afterward is much harder.
How do I install pre-commit?
Install it with pip, then confirm the version.
pip install pre-commit
pre-commit --version
In a Python project you can add it to requirements-dev.txt. There is also a zero-dependency .pyz zipapp on the project's GitHub releases.
What goes in the config file?
Create .pre-commit-config.yaml at the repository root. It holds a repos list, and each entry has a repo URL, a rev, and a list of hooks identified by id.
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
hooks:
- id: detect-private-key
- id: check-added-large-files
Add secret scanners and linters that fit your stack as further entries. Choose each hook by reading its repository, since a hook runs code on every developer machine.
How do I enable the hook and test it?
Run the install command, then run everything once.
pre-commit install
pre-commit run --all-files
The first writes the hook to .git/hooks/pre-commit so it runs on every git commit. The documentation recommends running against all files when you add new hooks, because a normal commit only checks changed files.
Why must I pin the rev?
Because the hook is third-party code. The documentation says rev should be an immutable reference such as a tag or commit SHA, and that branch names like main are not supported. To update, use autoupdate. The freeze flag stores commit hashes with the tag as a comment.
pre-commit autoupdate --freeze
Why repeat the check in CI?
A developer can skip hooks locally. The documentation suggests running the same all-files command in CI, which makes the check mandatory on every pull request.
Frequently asked questions
Can developers bypass pre-commit?
Yes, hooks can be skipped locally, so run the same hooks in CI to enforce them.
Does pre-commit scan the whole repository on commit?
No. A normal commit checks changed files. Run pre-commit with the run command and the all-files option to check everything.
Is it safe to use any hook repository?
Treat hooks as code you are choosing to run. Pin the revision and read the source before adding one.
What should I do about a secret that was already committed?
Revoke and rotate it first. See what to do when an API key leaks.
Sources
Last reviewed: 19 October 2026.