Перейти к содержанию
Innovialabs

Git hooks: автоматизация проверок с pre-commit и Husky

Продвинутое3 мин

Коротко

Git hooks — скрипты, которые Git запускает перед коммитом или пушем; фреймворк pre-commit (Python) и Husky с lint-staged (JS) делают их общими для всей команды и проверяют только изменённые файлы.

Короткий ответ

Git hooks — это скрипты, которые Git сам запускает в определённые моменты: перед коммитом, при записи сообщения коммита, перед пушем. Если скрипт завершился с ошибкой, действие отменяется.

Проблема «голых» хуков: они лежат в .git/hooks, а эта папка не попадает в репозиторий. Поэтому используют инструменты, которые хранят настройки в коде и ставят хуки каждому разработчику:

  • pre-commit — фреймворк на Python, работает с любыми языками, популярен в Python-проектах.
  • Husky + lint-staged — стандартная связка в JavaScript и TypeScript проектах.

Какие клиентские хуки полезны

ХукКогда срабатываетЧто обычно проверяют
pre-commitдо создания коммиталинтер, форматирование, секреты в коде
commit-msgпосле ввода сообщенияформат сообщения коммита
pre-pushперед отправкой на сервербыстрые тесты, сборка типов

Главный принцип: хук должен быть быстрым. Если коммит ждёт минуту, разработчики начнут обходить проверки.

Python: фреймворк pre-commit

Установите пакет и создайте в корне файл .pre-commit-config.yaml:

default_install_hook_types: [pre-commit, commit-msg]

repos:
  - 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-added-large-files

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

  - repo: https://github.com/compilerla/conventional-pre-commit
    rev: v3.4.0
    hooks:
      - id: conventional-pre-commit
        stages: [commit-msg]

Затем:

pip install pre-commit
pre-commit install          # ставит хуки в .git/hooks
pre-commit run --all-files  # первый прогон по всему проекту
pre-commit autoupdate       # обновить версии в rev

Что важно знать:

  • Каждый хук работает в своём изолированном окружении, версии зафиксированы в rev — у всей команды одинаковые результаты.
  • По умолчанию проверяются только файлы из коммита.
  • ruff здесь закрывает и линтинг, и форматирование; можно подключить black, isort, mypy и другие.

JavaScript: Husky и lint-staged

Husky управляет хуками, lint-staged запускает команды только для файлов, добавленных в индекс.

npm install --save-dev husky lint-staged
npx husky init

Команда husky init создаёт папку .husky и добавляет скрипт prepare, чтобы хуки ставились автоматически после npm install. Замените содержимое .husky/pre-commit:

npx lint-staged

Настройка lint-staged в package.json:

{
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{css,md,json}": "prettier --write"
  }
}

Проверка сообщений коммитов через commitlint:

npm install --save-dev @commitlint/cli @commitlint/config-conventional
echo "export default { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
echo 'npx --no -- commitlint --edit "$1"' > .husky/commit-msg

Теперь сообщение вида fix: исправить расчёт скидки пройдёт, а исправления — нет. Формат конфигурации commitlint зависит от того, использует ли проект ES-модули; сверяйтесь с документацией вашей версии.

Хуки не заменяют CI

Любой хук можно пропустить флагом git commit --no-verify, а у нового разработчика они могут быть просто не установлены. Поэтому:

  • те же проверки дублируются в CI — это последний рубеж;
  • хуки — это быстрая обратная связь до пуша, а не гарантия;
  • тяжёлые проверки (полный набор тестов, сборка) оставляйте в CI или в pre-push.

Частые ошибки

  • Запускать линтер по всему проекту на каждый коммит — медленно. Проверяйте только изменённые файлы.
  • Не фиксировать версии инструментов — у разных людей разные результаты.
  • Включить строгие правила сразу на старом проекте — сотни ошибок, и хуки отключат. Начните с форматирования, правила добавляйте постепенно.
  • Забыть про Windows: скрипты хуков должны работать в Git Bash, избегайте специфичных команд.

Частые вопросы

Да, фреймворк pre-commit не зависит от языка и умеет запускать Node-инструменты. Но в JS-проектах Husky и lint-staged привычнее, потому что ставятся вместе с npm-зависимостями.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.