git-hooks-suite
Collection de hooks Git pour l'automatisation des workflows : validation de messages de commit, lint pré-commit, notification post-merge.
Description & Examples
git-hooks-suite
A collection of Git hooks that automate and enforce workflow conventions at key points in the Git lifecycle. Covers commit validation, pre-commit quality gates, and post-merge notifications.
What it does
This plugin installs three hooks: pre-commit runs linting and formatting checks before a commit is recorded; commit-msg validates that the commit message follows the configured convention (Conventional Commits by default); post-merge triggers dependency installation and cache invalidation after a merge or pull.
When to use it
Use this plugin to enforce consistent commit history and prevent broken code from entering the repository. It is particularly useful for teams onboarding new contributors or for projects that feed commit messages into automated changelogs and release tooling.
Components
anchor
pre-commit
Hook
pre-commit hook
Runs quality checks on staged files before recording a commit. The hook aborts the commit if any check fails, printing a clear explanation of what needs to be fixed.
Checks performed
- Linting — runs the project's configured linter (ESLint, Pylint, PHP_CodeSniffer, Checkstyle) on staged files only
- Formatting — verifies that staged files conform to the project formatter (Prettier, Black, gofmt) without modifying them
- Secret detection — scans for patterns that look like API keys, tokens, or private keys
- Test smoke check — if a test file corresponding to a staged source file exists, runs that test in isolation
Behaviour
- Only staged files are checked (not the whole working tree)
- The hook is skipped automatically on merge commits and rebase operations
- Exit code 0 allows the commit to proceed; any non-zero exit aborts it
Bypassing (emergency use only)
git commit --no-verify -m "emergency fix"
Use --no-verify only when absolutely necessary. Bypasses are logged to .git/hooks-bypass.log with timestamp and author.
Configuration
Create a .pre-commit-config.yml at the project root to customise checks:
pre-commit:
skip-patterns:
- "generated/**"
- "*.min.js"
lint: true
format: check # "check" (fail if wrong) | "fix" (auto-fix and re-stage) | false
secrets: true
tests: false # set true to enable smoke tests
Troubleshooting
If the hook runs slowly, enable the staged-only optimisation (on by default) and ensure your linter supports --stdin-filename for per-file invocation rather than whole-project scans.
anchor
commit-msg
Hook
commit-msg hook
Validates commit messages against a configurable convention before the commit is finalised. Rejects commits that do not conform and prints a helpful error message with the expected format.
Default convention: Conventional Commits
The hook enforces the Conventional Commits specification by default:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Allowed types
feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
Examples of valid messages
feat(auth): add OAuth2 login flow
fix: prevent race condition in cache invalidation
docs: update API reference for v3 endpoints
refactor(payment): extract card validation to ValueObject
Examples of rejected messages
WIP ← no type prefix
Fix bug ← type not lowercase, missing colon
feat : add feature ← space before colon
FEAT(auth): something ← type must be lowercase
Error output
When a message is rejected, the hook prints:
[commit-msg] Commit message does not follow Conventional Commits format.
Expected: <type>[optional scope]: <short description>
Got: "Fix bug in login"
Allowed types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
Configuration
commit-msg:
convention: conventional-commits # "conventional-commits" | "custom" | false
min-length: 10
max-length: 100
require-scope: false
custom-pattern: "" # regex, used when convention is "custom"
Bypassing
git commit --no-verify
Bypass is discouraged for this hook since it directly affects changelog generation.
anchor
post-merge
Hook
post-merge hook
Runs automatically after a successful git merge or git pull. Handles housekeeping tasks that should happen whenever the working tree receives new commits from another branch or remote.
Actions performed
- Dependency sync — detects changes to dependency manifests and triggers the appropriate install command
- Cache invalidation — removes stale build artefacts when source files have changed in ways that could make them invalid
- Database migration check — warns if new migration files were pulled in that have not been applied
- Environment file check — alerts if
.env.examplechanged but the local.envwas not updated
Dependency detection
The hook compares the merged HEAD against ORIG_HEAD to detect changes:
| Changed file | Action |
|---|---|
package-lock.json / yarn.lock |
npm ci / yarn install --frozen-lockfile |
pom.xml |
mvn dependency:resolve -q |
requirements.txt / pyproject.toml |
pip install -r requirements.txt |
composer.lock |
composer install |
go.sum |
go mod download |
Output example
[post-merge] Detected changes in package-lock.json
[post-merge] Running: npm ci
[post-merge] Dependencies updated successfully.
[post-merge] ⚠ New migration files detected: 20240315_add_user_roles.sql
[post-merge] Run: ./scripts/migrate.sh
Configuration
post-merge:
install-deps: true
invalidate-cache: true
check-migrations: true
migration-dir: db/migrations
check-env: true
env-example: .env.example
Notes
- This hook does not run on rebase; use
post-rewritefor that scenario - Long-running install commands run asynchronously by default and print a completion notice when done