# Check Only Staged Files
## Rule
Pre-commit commands MUST use `{staged_files}` to check only staged files. Running tools on the entire codebase in pre-commit hooks is prohibited.
## Format
```yaml
# Good — staged files only
pre-commit:
commands:
lint:
glob: "*.{ts,tsx}"
run: npx eslint {staged_files}
```
```yaml
# Bad — checks entire codebase
pre-commit:
commands:
lint:
run: npx eslint src/
```
## File Placeholders
| Placeholder | Hook Stage | Description |
|-------------|-----------|-------------|
| `{staged_files}` | pre-commit | Files in the staging area |
| `{push_files}` | pre-push | Files changed since remote HEAD |
| `{all_files}` | any | All tracked files (avoid in hooks) |
| `{1}` | commit-msg | The commit message file path |
## Combined with Glob Filtering
```yaml
pre-commit:
commands:
# Only staged TypeScript files
ts-lint:
glob: "*.{ts,tsx}"
run: npx eslint {staged_files}
# Only staged Python files
py-lint:
glob: "*.py"
run: ruff check {staged_files}
# Only staged Terraform files
tf-scan:
glob: "*.tf"
run: checkov -f {staged_files}
```
## Exceptions
- Secret scanning (`gitleaks protect --staged`) inherently operates on staged content
- Commit message validation uses `{1}` (the message file)
- Type checking (`tsc --noEmit`) needs the full project — move to pre-push
## Anti-Patterns
- Using `{all_files}` in pre-commit (checks everything, very slow)
- Hardcoding directory paths instead of `{staged_files}`
- Running `tsc --noEmit` in pre-commit (needs full codebase, too slow)
- Not using glob with `{staged_files}` (passes wrong file types to tools)