What is .pre-commit-config.yaml
Complete guide to pre-commit configuration files and Git hooks
Introduction
The .pre-commit-config.yaml file is a configuration file used by the pre-commit framework. It defines a set of hooks that run automatically before each Git commit, helping maintain code quality, consistency, and preventing common mistakes.
What is Pre-commit?
Pre-commit is a framework for managing and maintaining multi-language pre-commit hooks. It allows you to run checks and formatters on your code before it's committed to your repository, ensuring code quality and consistency across your project.
Key Benefits
- Automatically runs code quality checks before commits
- Enforces coding standards and formatting
- Catches errors early in the development process
- Maintains consistency across team members
- Supports multiple programming languages
File Structure
A basic .pre-commit-config.yaml file structure:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
Key Components
repos- List of repositories containing hooksrepo- URL or local path to the hook repositoryrev- Version/tag of the repository to usehooks- List of hooks to run from the repositoryid- Identifier of the specific hook
Common Pre-commit Hooks
Basic Hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace # Remove trailing whitespace
- id: end-of-file-fixer # Ensure files end with newline
- id: check-yaml # Validate YAML files
- id: check-json # Validate JSON files
- id: check-added-large-files # Prevent large files
- id: check-merge-conflict # Detect merge conflict markers
- id: check-case-conflict # Check for case conflicts
- id: debug-statements # Remove debug statements
Language-Specific Hooks
# Python hooks
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
# JavaScript/TypeScript hooks
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.44.0
hooks:
- id: eslint
Complete Configuration Example
A comprehensive .pre-commit-config.yaml example:
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
# General file checks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-json
- id: check-added-large-files
args: ['--maxkb=1000']
- id: check-merge-conflict
- id: check-case-conflict
- id: mixed-line-ending
- id: check-docstring-first
# Python formatting and linting
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
language_version: python3
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
args: ['--max-line-length=88', '--extend-ignore=E203']
# YAML linting
- repo: https://github.com/adrienverge/yamllint
rev: v1.32.0
hooks:
- id: yamllint
args: ['-d', '{extends: default, rules: {line-length: {max: 120}}}']
# Markdown linting
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.35.0
hooks:
- id: markdownlint
Installation and Setup
Step 1: Install pre-commit
# Using pip
pip install pre-commit
# Using conda
conda install -c conda-forge pre-commit
# Using homebrew (macOS)
brew install pre-commit
Step 2: Create .pre-commit-config.yaml
Create the configuration file in your repository root:
# Create file in repository root
touch .pre-commit-config.yaml
# Add your hooks configuration (see examples above)
Step 3: Install Git hooks
# Install hooks into .git/hooks/
pre-commit install
# Install hooks for commit-msg
pre-commit install --hook-type commit-msg
# Install hooks for pre-push
pre-commit install --hook-type pre-push
Step 4: Test the hooks
# Run hooks on all files
pre-commit run --all-files
# Run a specific hook
pre-commit run trailing-whitespace --all-files
Advanced Configuration
Hook Arguments
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-added-large-files
args: ['--maxkb=500'] # Custom arguments
- id: trailing-whitespace
args: ['--markdown-linebreak-ext=md']
File Filtering
repos:
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
files: ^src/ # Only run on files in src/
exclude: ^tests/ # Exclude tests directory
Local Hooks
repos:
- repo: local
hooks:
- id: custom-script
name: Run custom script
entry: bash scripts/check.sh
language: system
files: \.(py|js)$
Best Practices
-
•
Pin hook versions - Use specific version tags (rev) instead of branches
-
•
Start simple - Begin with basic hooks and add more as needed
-
•
Run on all files initially - Use
pre-commit run --all-filesto fix existing issues -
•
Document custom hooks - Add comments explaining why specific hooks are used
-
•
Keep hooks fast - Avoid slow hooks that delay commits significantly
Troubleshooting
Issue: Hooks not running
Ensure hooks are installed:
# Reinstall hooks
pre-commit install
# Verify installation
ls .git/hooks/pre-commit
Issue: Skip hooks temporarily
Use --no-verify flag (use sparingly):
# Skip pre-commit hooks
git commit --no-verify -m "message"
# Note: This bypasses all hooks, use only when necessary