Git-хуки

Материал из llmdocs — справочник разработчика
Портал: Git, CI/CD, DevOps
Git-хуки
Где лежат.git/hooks/ (или core.hooksPath)
Типыклиентские и серверные
Популярные клиентскиеpre-commit, commit-msg, pre-push
Серверныеpre-receive, update, post-receive
Менеджерыpre-commit (Python), husky (Node.js), lefthook (Go)
Обходgit commit --no-verify

Git-хуки (англ. git hooks) — программы, которые Git автоматически запускает в определённые моменты своей работы: перед созданием коммита, после смены ветки, перед отправкой изменений на сервер, при приёме пуша на сервере. Если хук завершается с ненулевым кодом, Git отменяет операцию. Хуки используют, чтобы ловить ошибки как можно раньше — запускать линтер и форматтер, проверять сообщения коммитов, не пропускать в репозиторий секреты — ещё до того, как изменения попадут в CI/CD.

Как устроены

Хуки — это исполняемые файлы с фиксированными именами в каталоге .git/hooks/. При git init там создаются примеры с суффиксом .sample; чтобы включить хук, достаточно убрать суффикс и сделать файл исполняемым.[1] Язык не важен: подойдёт shell, Python, Node.js — что угодно с правильной строкой #!.

Каталог .git/ не попадает в репозиторий, поэтому хуки не передаются при клонировании — это сделано намеренно, иначе любой репозиторий мог бы выполнить код на машине разработчика. Чтобы поделиться хуками с командой, их кладут в отслеживаемую папку и указывают Git путь к ней:

git config core.hooksPath .githooks

Либо используют менеджеры хуков, о которых ниже.

Клиентские хуки

Хук Когда Типичное применение
pre-commit перед созданием коммита линтеры, форматтеры, поиск секретов
prepare-commit-msg перед открытием редактора шаблон, номер задачи из имени ветки
commit-msg после ввода сообщения проверка формата (Conventional Commits)
post-commit после коммита уведомления
post-checkout, post-merge после смены ветки, слияния установить зависимости, если изменился lock-файл
pre-rebase перед rebase запрет переписывать опубликованные ветки
pre-push перед отправкой быстрые тесты

Пример простого pre-commit, не дающего закоммитить отладочный вывод:

#!/bin/sh
if git diff --cached -U0 | grep -E '^\+.*(console\.log|breakpoint\(\))'; then
  echo "Уберите отладочный код перед коммитом" >&2
  exit 1
fi

Хук должен проверять именно индекс (git diff --cached), а не рабочую копию — иначе в проверку попадут незастейдженные правки.

Серверные хуки

На сервере выполняются pre-receive, update и post-receive.[2] Они могут отклонить пуш (например, в защищённую ветку или без подписи) или запустить действие после него — исторически так делали простейший деплой: post-receive выкладывал код в каталог сайта. На GitHub и GitLab произвольные серверные хуки обычно недоступны (GitLab разрешает их на собственной установке); вместо них используют правила защиты веток, push rules и вебхуки, а проверки — в CI.

Менеджеры хуков

  • pre-commit — фреймворк на Python с тысячами готовых хуков; конфигурация в .pre-commit-config.yaml, каждое средство ставится в изолированное окружение. Работает для любых языков.[3]
  • husky — популярный выбор в экосистеме JavaScript, хуки хранятся в .husky/; часто в паре с lint-staged, который проверяет только изменённые файлы.[4]
  • lefthook — быстрый менеджер на Go с параллельным запуском и конфигурацией в YAML.[5]
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.7.0
    hooks:
      - id: ruff
        args: [--fix]
      - id: ruff-format
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.21.0
    hooks:
      - id: gitleaks

После pre-commit install хуки срабатывают на каждом коммите и проверяют только изменённые файлы; pre-commit run --all-files прогоняет весь репозиторий. Здесь Ruff проверяет Python-код, а gitleaks ищет случайно добавленные ключи и пароли.

Проверка сообщений коммитов

Хук commit-msg часто проверяет соответствие соглашению Conventional Commits (feat: ..., fix(api): ...) с помощью commitlint.[6] На таких сообщениях строится автоматическая генерация CHANGELOG и выбор следующей версии по правилам семантического версионирования.

Ограничения

Клиентские хуки — удобство, а не гарантия: их легко обойти флагом --no-verify, а у нового участника они не установлены, пока он не выполнит установку. Поэтому все обязательные проверки дублируют в CI, а хуки делают быстрыми — несколько секунд, — иначе разработчики начнут их отключать. Долгие тесты лучше оставить для pre-push или CI.

См. также

Источники

  1. Git Documentation — githooks
  2. Pro Git — Customizing Git: Git Hooks
  3. pre-commit — framework for managing git hooks
  4. husky
  5. lefthook
  6. Conventional Commits