🧪Hook
Block commits without tests
PreToolUse hook that blocks git commit when source files are staged without matching tests.
- Surfaces
- hook · trigger
- Complexity
- intermediate
- Trigger
- hook
- Est. tokens
- 0
What It Does
PreToolUse hook that runs before any git commit command. It inspects the staged diff and, if source files are staged without any matching test or spec files, exits with code 2 to block the commit. Claude sees the block and is instructed to add tests first.
When It Triggers
- ▸PreToolUse on Bash commands matching ^git commit
- ▸Fires before the commit executes, not after
SKILL.md
markdown
---
name: block-commits-no-tests
description: PreToolUse hook that blocks Bash git commit commands when no test files are staged alongside code changes. Enforces test-with-code discipline.
---
# Block Commits Without Tests
## How It Works
Before Claude runs `git commit`, the hook inspects the staged diff. If
source files are staged without matching test files, the commit is blocked
and Claude is asked to add tests first.
settings.json
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"commandMatcher": "^git commit",
"command": "bash scripts/check_tests.sh"
}
]
}
}
scripts/check_tests.sh
bash
#!/usr/bin/env bash
set -euo pipefail
STAGED=$(git diff --cached --name-only)
HAS_SRC=$(echo "$STAGED" | grep -E '^src/.*\.(ts|tsx|py)$' || true)
HAS_TEST=$(echo "$STAGED" | grep -E '(test|spec)\.(ts|tsx|py)$|tests/' || true)
if [ -n "$HAS_SRC" ] && [ -z "$HAS_TEST" ]; then
echo "BLOCKED: source files staged without tests" >&2
exit 2
fi
exit 0
Gotchas
- ▸Too aggressive blocks legitimate docs-only or config commits — tune the HAS_SRC regex for your layout.
- ▸The hook exits 2 to signal a block; exit 0 allows the commit, exit 1 is a hard error.
- ▸Pair with a "skip-tests" escape hatch for rare emergencies (env var SKIP_TEST_CHECK=1).