20+ Pre-commit Hooks

Automated quality checks that run before every commit, catching issues before they reach your repository.

📍 When These Hooks Run

Pre-commit hooks execute automatically:

  • Every time you run git commit
  • Before the commit is created
  • If any hook fails, the commit is blocked
  • Many hooks auto-fix issues (you just need to re-commit)

Why Pre-commit Hooks Matter

Pre-commit hooks are your first line of defense against:

  • Secrets in code - Detect API keys, passwords, credentials
  • Code quality issues - Enforce formatting, catch linting errors
  • Security vulnerabilities - Find unsafe patterns, insecure configs
  • File corruption - Detect broken symlinks, large files, merge conflicts

By running checks before commit, you catch problems early - before they enter your repository, before CI fails, before code review, and before production.

Formatting Hooks (Auto-fix)

Code Formatters

These hooks automatically format your code to match project standards.

  • black Python formatter (88 char line length)
  • isort Python import sorter
  • prettier JavaScript/TypeScript/JSON/YAML/Markdown formatter
  • shfmt Shell script formatter
  • end-of-file-fixer Ensures files end with newline
  • trailing-whitespace Removes trailing spaces
  • mixed-line-ending Fixes CRLF/LF inconsistencies

✨ Auto-fix Behavior

These hooks automatically modify files. After running:

  1. Check which files were modified: git status
  2. Review changes: git diff
  3. Add formatted files: git add .
  4. Commit again: git commit

Linting Hooks (Quality Checks)

Code Linters

These hooks analyze code for errors, style issues, and potential bugs.

  • pylint Python linter (PEP 8 compliance)
  • flake8 Python style guide enforcement
  • mypy Python type checker
  • shellcheck Shell script linter (catches common bugs)
  • eslint JavaScript/TypeScript linter
  • yamllint YAML syntax and style checker
  • markdownlint Markdown style and syntax checker

Example Error:

shellcheck detected issues in script.sh:

Line 5: rm -rf $USER_DIR/temp
            ^-------^ SC2086: Quote this to prevent word splitting

Fix: rm -rf "${USER_DIR}/temp"

Security Hooks (Critical)

Secret Detection

These hooks prevent committing sensitive information.

  • detect-secrets Finds API keys, passwords, tokens
  • detect-aws-credentials Detects AWS access keys and secrets
  • detect-private-key Finds SSH, TLS, GPG private keys

🚨 When Secrets Are Detected

If a hook finds secrets:

  1. Commit is blocked immediately
  2. Hook shows which files contain secrets
  3. Remove secrets from files
  4. Move to environment variables or .env file
  5. Commit again

Example Detection:

detect-secrets....................................................Failed
- hook id: detect-secrets

Potential secret found in config.py:
  Line 15: api_key = "sk-1234567890abcdef"
           ^-------^ Appears to be an API key

Fix: Move to environment variable
  api_key = os.environ.get("API_KEY")

File Integrity Hooks

File Safety Checks

These hooks prevent corrupted or problematic files from being committed.

  • check-merge-conflict Detects unresolved merge conflict markers
  • check-added-large-files Blocks files larger than 500KB
  • check-symlinks Detects broken symbolic links
  • check-yaml Validates YAML syntax
  • check-json Validates JSON syntax
  • check-toml Validates TOML syntax
  • check-executables-have-shebangs Ensures scripts have proper shebang

Setup Pre-commit Hooks

Automatic Setup (Recommended)

# Clone the Guardrails-AI repository
git clone https://github.com/christopherpaquin/Guardrails-AI .ai-guardrails

# Copy template infrastructure
./. ai-guardrails/template/bootstrap-guardrails.sh

# Run setup script
./scripts/setup-precommit.sh

# Test it works
pre-commit run --all-files

Manual Setup

# Install pre-commit
pip install pre-commit

# Copy configuration
cp .ai-guardrails/.pre-commit-config.yaml .

# Install hooks
pre-commit install
pre-commit install --hook-type commit-msg

# Run on all files (first time)
pre-commit run --all-files

Verification

Test that pre-commit is working:

# Create a test file with issues
echo "api_key = 'sk-test123'" > test.py

# Try to commit (should fail)
git add test.py
git commit -m "test"

# Expected: detect-secrets hook should block the commit

Managing Hooks

Using Management Scripts

# List all hooks
./scripts/manage-precommit-hooks.sh list

# Disable expensive hooks during development
./scripts/manage-precommit-hooks.sh disable shellcheck
./scripts/manage-precommit-hooks.sh disable pylint

# Re-enable later
./scripts/manage-precommit-hooks.sh enable shellcheck

# Show hook configuration
./scripts/manage-precommit-hooks.sh show detect-secrets

Manual Hook Management

Edit .pre-commit-config.yaml to customize hooks:

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: trailing-whitespace
        # Exclude markdown files
        exclude: '\\.md$'
      
      - id: check-added-large-files
        # Change size limit to 1MB
        args: ['--maxkb=1000']

Skipping Hooks (Emergency Only)

Not recommended! But if you must:

# Skip all hooks (use with caution!)
git commit --no-verify -m "emergency fix"

# Skip specific hook
SKIP=shellcheck git commit -m "skip shellcheck for this commit"

Ready to Enforce Quality?

Install pre-commit hooks in your project and catch issues before they're committed.

Get Started