Put only fast, local, low-noise checks in a pre-commit hook: formatting, simple lint rules, and checks on the files being committed. Leave full dependency and code scans for the pull request. A slow hook gets bypassed, and a hook alone cannot enforce anything.
What a hook is, and what it is not
A Git hook is a script that Git runs at a defined moment, such as before a commit completes. The Pro Git book explains that the pre-commit hook runs before you type a commit message, and that exiting non-zero aborts the commit. It also notes you can bypass the hook with the no-verify flag on the commit command.
The pre-commit framework describes the goal in plain terms: hooks are useful for identifying simple issues before submission to code review, so reviewers can focus on the design of a change instead of trivial nitpicks. That framing is a good guide to what belongs there.
The test for a pre-commit check
A check belongs in the hook if all of these are true:
- It finishes in a few seconds on the files in the commit.
- It needs no network call or large data download.
- Its findings are almost always real, so people trust it.
- A developer can fix the result without a meeting.
If a check fails any of these, move it to the pull request. Hooks that take too long teach people to commit with the bypass flag, and then you have the slowness and no check.
Good candidates and poor candidates
| Check | Pre-commit? | Reason |
|---|---|---|
| Formatter and trailing whitespace | Yes | Instant, no judgment needed |
| Lint rules on staged files | Yes | Scoped to the change |
| Check for obviously unwanted files, such as key files | Yes | Cheap and high value |
| Full dependency vulnerability scan | No | Needs fresh advisory data and the whole tree |
| Whole-repository static analysis | No | Slow, noisy on large repos |
| Container image scan | No | Needs a built image |
The hook can still protect the repository from a mistake the author would regret, like committing a private key file by name. Just keep the logic simple.
Hooks do not enforce policy
The Pro Git documentation is direct about this: client-side hooks are not copied when you clone a repository, so if you want to enforce a policy you should do it on the server side. A person has to install the framework, and a person can skip it.
That means every hook check should have a twin in CI. The hook gives fast feedback. The shared check gives control. If the two disagree, CI wins.
A rollout in three steps
- Choose two or three fast checks the team agrees on.
- Add a config file to the repository and document the one install command.
- Run the same checks in CI so the result cannot be skipped.
Review the list every quarter and remove any check people routinely bypass.
Where Safeguard fits
Heavier checks such as dependency scanning, reachability analysis, and policy gates fit the pull request, and Safeguard runs them there. The CLI (1.4.0 on the download page) can also run scans from a terminal or CI job. A free scan is available at https://gold.safeguard.sh/scan.
Quick check
Can a pre-commit hook replace CI scanning?
No. A hook runs only where it is installed and can be bypassed. Use it for quick feedback and keep an enforced check in CI.
How long should a pre-commit hook take?
Short enough that nobody is tempted to skip it, usually a few seconds. If a check takes longer, move it to the pull request.
Sources
Last reviewed: 19 October 2026.