pre-commit-hooks

verified

e9adc444-ab38-44b7-9315-bb613c8d730d

Wire `pre-commit` to run linters, formatters, type-checks, and secret scans automatically on every commit. Use to catch issues at commit time instead of in CI.

Metadata

Skill ID
e9adc444-ab38-44b7-9315-bb613c8d730d
Version
1
Owner
387274b7-2891-478b-81b8-e11d5adb9319
Tags
pre-commithooksautomationquality-gatelintgit-hooks
Signature
verified
Integrity
OK
Content hash
421f8783ddbeabb49c716e55b6ba9a15e431e104ddba2972f1c10b2b13df94c6
Created
2026-08-15T05:27:04Z

Skill file

Raw skill file (markdown source)
# Pre-commit Hooks

Use when wiring automated checks to run on every `git commit` — so linters, formatters, type-checks, and secret scans fire before code ever reaches CI.

## The `.pre-commit-config.yaml` Anatomy

```yaml
# .pre-commit-config.yaml
repos:
  # 1. Generic whitespace/file hygiene
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-json
      - id: check-merge-conflict
      - id: check-added-large-files
        args: ["--maxkb=1024"]

  # 2. Python linter + formatter
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.5.0
    hooks:
      - id: ruff
        args: [--fix]
      - id: ruff-format

  # 3. Type checking (slower — consider running only on changed files)
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.10.0
    hooks:
      - id: mypy
        additional_dependencies: [types-requests]

  # 4. Secret scanning
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.0
    hooks:
      - id: gitleaks
```

## Install and First Run

```bash
pip install pre-commit

# Install the git hook
pre-commit install

# Run against ALL files once (clears the backlog so future commits are clean)
pre-commit run --all-files

# Test on a single file
pre-commit run ruff --files path/to/file.py
```

## Stages (when hooks run)

```yaml
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.5.0
    hooks:
      - id: ruff
        stages: [commit]       # run on `git commit`
  - repo: local
    hooks:
      - id: run-tests
        name: run-tests
        entry: pytest -x
        language: system
        stages: [push]         # run only on `git push`, not every commit
```

## CI Parity

Run the exact same hooks in CI so local and remote are identical:

```yaml
# .github/workflows/pre-commit.yml
name: pre-commit
on: [push, pull_request]
jobs:
  pre-commit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - run: pip install pre-commit
      - run: pre-commit run --all-files
```

## Skipping with Cause (the discipline)

```bash
# Skipping is allowed, but ONLY with an explicit reason
SKIP=mypy git commit -m "docs: fix typo in README"

# NEVER: git commit --no-verify  (bypasses EVERYTHING silently)
```

Rule: `SKIP=mypy` names the one hook you're skipping. `--no-verify` skips everything with no trail.

## Guardrails

- **Never** make `--no-verify` a habit — it silently disables all safety checks, including secret scanning.
- **Never** run slow hooks (mypy, full test suite) on every commit — push them to `stages: [push]` or leave them to CI.
- **Always** pin hook versions (`rev: v4.6.0`) — floating `main` branches break reproducibility.
- **Always** commit `.pre-commit-config.yaml` so every dev gets the same hooks.

## Pitfalls

- **Hooks too slow on every commit**: mypy or a full test suite on each commit makes devs hate pre-commit and bypass it. Keep commit-stage hooks fast (<5s).
- **Bypassing with `--no-verify` as a habit**: The moment `--no-verify` becomes the default muscle memory, all your guardrails are gone.
- **Never running `--all-files` first**: Newly-installed hooks only check changed files, so pre-existing issues slip through and CI (running `--all-files`) fails on unrelated code.
- **Version drift**: The hook runs `rev: main` locally and CI runs a different version — different results. Pin exact versions.
- **Autofix hooks that don't stage their changes**: `ruff --fix` modifies files but doesn't re-add them. The commit goes through with stale content. Ensure hooks that modify files are set up to re-stage (pre-commit handles this automatically for most).

## Verify / Checklist

- [ ] `pre-commit install` succeeded (check `.git/hooks/pre-commit` exists)
- [ ] `.pre-commit-config.yaml` committed and all versions pinned
- [ ] `pre-commit run --all-files` passes clean
- [ ] Secret scanner (gitleaks) included in the hook set
- [ ] Commit-stage hooks complete in under ~5 seconds
- [ ] CI runs `pre-commit run --all-files` for parity
- [ ] Team understands `SKIP=` (with reason) vs `--no-verify` (never)

Attached files

No attached files.