← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Git Hooks

git Intermediate
debt(d7/e3/b5/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The detection_hints note that style errors and linting failures only appear in CI (not locally) and slow feedback loops are the symptom — these issues surface only when someone notices CI failing repeatedly or reviews the repo setup, not through automated static analysis. Tools like captainhook, grumphp, husky, and pre-commit exist to address the gap but their absence is not auto-detected.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix points to adopting a tool like CaptainHook or GrumPHP with hook configuration — a small but non-trivial setup task involving config files and team onboarding. It's more than a one-line patch but contained within the repository's tooling setup rather than spanning multiple application components.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). The common_mistakes show that missing or slow hooks impose a persistent tax: every developer gets a slower feedback loop, team members running without hooks create inconsistency, and undocumented install steps mean new clones silently lack protection. This affects multiple work streams (onboarding, daily commits, CI round-trips) but doesn't reshape the entire codebase architecture.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception is explicit: developers commonly believe git hooks replace CI, but hooks are local-only and trivially bypassed with --no-verify. This directly contradicts the mental model that 'a hook is a gate' — the 'obvious' interpretation of a pre-commit hook is that it enforces policy, when in reality it is purely advisory and skippable.

About DEBT scoring →

Also Known As

pre-commit hook commit-msg hook Husky CaptainHook

TL;DR

Scripts that run automatically at specific points in the git workflow — pre-commit for linting, pre-push for tests, commit-msg for message format enforcement.

Explanation

Git hooks live in .git/hooks/ and are not version controlled by default. Types: pre-commit (run before commit, exit 1 to abort), commit-msg (validate message format), pre-push (run before push to remote), post-merge (run after merge — useful for dep updates), pre-rebase. For team-shared hooks, use a tools/hooks/ directory committed to the repo and a setup script that symlinks them, or Husky (Node.js projects), CaptainHook (PHP projects).

Common Misconception

Git hooks replace CI — hooks run only locally and can be bypassed with --no-verify; CI is the authoritative gate, hooks are developer convenience.

Why It Matters

Pre-commit hooks catch formatting and obvious errors before they reach CI — saving the round-trip of push → CI failure → fix → push for trivially preventable issues.

Common Mistakes

  • Slow pre-commit hooks — hooks that take more than 5-10 seconds get bypassed with --no-verify.
  • Storing hooks only in .git/hooks/ — not version controlled; new clones don't get them.
  • Not documenting how to install hooks in README/Makefile — team members run without them.
  • Pre-push hooks that run the entire test suite — too slow; run fast lint checks in pre-commit, reserve tests for CI.

Code Examples

✗ Vulnerable
# Hook not shared — only in .git/hooks/ (not version controlled):
# New developer clones repo
# .git/hooks/ is empty — no hooks installed
# They commit without linting, push fails CI on formatting
✓ Fixed
# CaptainHook for PHP — shared, version controlled:
# composer require --dev captainhook/captainhook
# captainhook.json (committed):
{
  "pre-commit": {
    "enabled": true,
    "actions": [
      {"action": "vendor/bin/php-cs-fixer fix --dry-run"},
      {"action": "vendor/bin/phpstan analyse --no-progress"}
    ]
  },
  "commit-msg": {
    "enabled": true,
    "actions": [{"action": "\\CaptainHook\\App\\Hook\\Message\\Action\\Regex",
      "options": {"regex": "/^(feat|fix|docs|chore|refactor|test)(\\(.+\\))?: .{3,}/"}
    }]
  }
}
# README: 'Run: vendor/bin/captainhook install'

Added 15 Mar 2026
Edited 22 Mar 2026
Views 31
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 3 pings F 0 pings S 1 ping S 0 pings M 1 ping T 0 pings W 0 pings T 3 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 0 pings S
No pings yet today
Amazonbot 1
Amazonbot 17 Ahrefs 3 Perplexity 2 Google 2 Majestic 1
crawler 24 crawler_json 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Use pre-commit, commit-msg, and pre-push hooks via a tool like CaptainHook or GrumPHP — these run locally before code reaches CI, giving faster feedback
📦 Applies To
git any
🔗 Prerequisites
🔍 Detection Hints
Style errors and linting failures only caught in CI not locally; inconsistent commit messages with no commit-msg hook; slow feedback loop for code quality
Auto-detectable: ✓ Yes captainhook grumphp husky pre-commit
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✓ Auto-fixable Fix: Low Context: File

✓ schema.org compliant