Terminal GuideTerminal Guide
pre-commit icon

pre-commit

Git Tools
macOSLinuxWindows
Python

Git hooks framework for code quality.

Official Website

Features

Git HooksMulti-language SupportAuto UpdateCI IntegrationCustom Hooks

Installation

Homebrew
brew install pre-commit
pip
pip install pre-commit

Why Use pre-commit?

pre-commit is a framework for managing Git hooks. It automatically runs code quality checks before committing, ensuring consistent code quality across the team.

Automatic Code Quality Checks

Automatically runs linters, formatters, and security scans before committing. Prevents problematic code from entering the repository.

Multi-Language Support

Unified management of tools for Python, JavaScript, Go, Rust, Ruby, Shell, and more languages.

Automatic Updates

Hook versions can be automatically updated. Always run checks with the latest tools.

CI Integration

Easy integration with CI services like GitHub Actions, GitLab CI, and CircleCI. Run the same checks locally and in CI.

Installation

Installation
# Install with pip (recommended)
pip install pre-commit

# macOS (Homebrew)
brew install pre-commit

# conda
conda install -c conda-forge pre-commit

# pipx (global install)
pipx install pre-commit

# Check version
pre-commit --version

Basic Usage

1. Create Configuration File

Create .pre-commit-config.yaml at the repository root.

.pre-commit-config.yaml
# .pre-commit-config.yaml (basic example)
repos:
  # Common checks
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: trailing-whitespace      # Remove trailing whitespace
      - id: end-of-file-fixer        # Add newline at end of file
      - id: check-yaml               # YAML syntax check
      - id: check-json               # JSON syntax check
      - id: check-added-large-files  # Prevent adding large files
      - id: detect-private-key       # Detect accidental private key commits

  # For Python
  - repo: https://github.com/psf/black
    rev: 24.1.0
    hooks:
      - id: black                    # Code formatter

  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.1.14
    hooks:
      - id: ruff                     # Linter
        args: [--fix]
      - id: ruff-format              # Formatter

2. Install Hooks

Hook Installation
# Install Git hooks
pre-commit install

# Also install commit-msg hook (for commit message validation)
pre-commit install --hook-type commit-msg

# Install all hook types
pre-commit install --install-hooks

# Verify installation
ls -la .git/hooks/

3. Manual Execution

Manual Execution
# Run on all files
pre-commit run --all-files

# Run specific hook only
pre-commit run black --all-files

# Staged files only (same as on commit)
pre-commit run

# Run on specific files
pre-commit run --files src/main.py src/utils.py

Popular Hooks

JavaScript/TypeScript

JavaScript/TypeScript hooks
repos:
  # ESLint
  - repo: https://github.com/pre-commit/mirrors-eslint
    rev: v8.56.0
    hooks:
      - id: eslint
        files: \.[jt]sx?$
        types: [file]
        additional_dependencies:
          - eslint@8.56.0
          - eslint-config-prettier@9.1.0
          - '@typescript-eslint/parser@6.19.0'
          - '@typescript-eslint/eslint-plugin@6.19.0'

  # Prettier
  - repo: https://github.com/pre-commit/mirrors-prettier
    rev: v3.1.0
    hooks:
      - id: prettier
        types_or: [javascript, jsx, ts, tsx, json, yaml, markdown]

Python

Python hooks
repos:
  # Black (formatter)
  - repo: https://github.com/psf/black
    rev: 24.1.0
    hooks:
      - id: black
        language_version: python3.11

  # Ruff (fast linter/formatter)
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.1.14
    hooks:
      - id: ruff
        args: [--fix, --exit-non-zero-on-fix]

  # mypy (type checking)
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.8.0
    hooks:
      - id: mypy
        additional_dependencies: [types-requests]

  # isort (organize imports)
  - repo: https://github.com/pycqa/isort
    rev: 5.13.2
    hooks:
      - id: isort

Security & Secret Detection

Security Hooks
repos:
  # Secret detection
  - repo: https://github.com/Yelp/detect-secrets
    rev: v1.4.0
    hooks:
      - id: detect-secrets
        args: ['--baseline', '.secrets.baseline']

  # Gitleaks (secret/API key detection)
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.1
    hooks:
      - id: gitleaks

  # TruffleHog (secret scanning)
  - repo: https://github.com/trufflesecurity/trufflehog
    rev: v3.63.7
    hooks:
      - id: trufflehog
        entry: bash -c 'trufflehog git file://. --only-verified --fail'

Commit Messages

Commit Message Hooks
repos:
  # Conventional Commits
  - repo: https://github.com/compilerla/conventional-pre-commit
    rev: v3.1.0
    hooks:
      - id: conventional-pre-commit
        stages: [commit-msg]
        args: [feat, fix, docs, style, refactor, perf, test, build, ci, chore]

  # commitlint
  - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
    rev: v9.11.0
    hooks:
      - id: commitlint
        stages: [commit-msg]
        additional_dependencies: ['@commitlint/config-conventional']

Settings and Customization

Hook Configuration Options

Hook Configuration Options
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: check-added-large-files
        args: ['--maxkb=500']           # Detect files over 500KB
        exclude: ^docs/images/          # Exclude specific paths

      - id: trailing-whitespace
        files: \.(py|js|ts)$            # Target specific extensions only
        exclude: ^tests/fixtures/       # Exclude test data

      - id: check-yaml
        args: ['--unsafe']              # Custom arguments
        stages: [commit, push]          # Specify stages to run

  - repo: local
    hooks:
      - id: custom-script
        name: Custom validation
        entry: ./scripts/validate.sh
        language: script
        files: \.py$
        pass_filenames: true            # Pass filenames as arguments
        always_run: false               # Run only when changes exist

Creating Local Hooks

Local Hooks
repos:
  - repo: local
    hooks:
      # Shell script
      - id: check-todo
        name: Check for TODO comments
        entry: bash -c 'grep -rn "TODO" --include="*.py" && exit 1 || exit 0'
        language: system
        types: [python]

      # Python script
      - id: custom-python-check
        name: Custom Python check
        entry: python scripts/custom_check.py
        language: python
        files: \.py$
        additional_dependencies: [click]

      # Using Docker
      - id: docker-lint
        name: Docker lint
        entry: docker run --rm -v "$PWD:/app" hadolint/hadolint hadolint
        language: docker
        files: Dockerfile

CI Integration

GitHub Actions

.github/workflows/pre-commit.yml
# .github/workflows/pre-commit.yml
name: pre-commit

on:
  pull_request:
  push:
    branches: [main]

jobs:
  pre-commit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - uses: pre-commit/action@v3.0.1

GitLab CI

.gitlab-ci.yml
# .gitlab-ci.yml
pre-commit:
  stage: test
  image: python:3.11
  variables:
    PRE_COMMIT_HOME: $CI_PROJECT_DIR/.cache/pre-commit
  cache:
    paths:
      - .cache/pre-commit
  before_script:
    - pip install pre-commit
  script:
    - pre-commit run --all-files

Command List

CommandDescription
pre-commit installInstall Git hooks
pre-commit uninstallUninstall Git hooks
pre-commit runRun on staged files
pre-commit run --all-filesRun on all files
pre-commit autoupdateUpdate hook versions to latest
pre-commit cleanClear cache
pre-commit gcRemove unused cache
pre-commit sample-configOutput sample configuration file

Tips

  • *To skip hooks when committing, use git commit --no-verify (emergency only)
  • *Regularly run pre-commit autoupdate to keep hooks up to date
  • *Running the same hooks in CI catches cases that are skipped locally
  • *Use exclude patterns to exclude large files or specific paths
  • *Setting fail_fast: true stops at the first error (useful for debugging)
  • *Document in README that all team members should run pre-commit install

Official Resources

Written by Dai AokiPublished: 2026-01-20

Related Articles

Explore More