# Git-хуки

> Скрипты, которые Git запускает на определённых событиях — перед коммитом, при пуше, на сервере при приёме изменений; основа линтинга и проверок до CI.

Источник: https://llmdocs.ru/wiki/git-hooks/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Где лежат**: .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](https://llmdocs.ru/wiki/git.md) автоматически запускает в определённые моменты своей работы: перед созданием коммита, после смены ветки, перед отправкой изменений на сервер, при приёме пуша на сервере. Если хук завершается с ненулевым кодом, Git отменяет операцию. Хуки используют, чтобы ловить ошибки как можно раньше — запускать линтер и форматтер, проверять сообщения коммитов, не пропускать в репозиторий секреты — ещё до того, как изменения попадут в [CI/CD](https://llmdocs.ru/wiki/ci-cd.md).

## Как устроены

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

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

```bash
git config core.hooksPath .githooks
```

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

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

| Хук | Когда | Типичное применение |
|---|---|---|
| `pre-commit` | перед созданием коммита | линтеры, форматтеры, поиск секретов |
| `prepare-commit-msg` | перед открытием редактора | шаблон, номер задачи из имени ветки |
| `commit-msg` | после ввода сообщения | проверка формата (Conventional Commits) |
| `post-commit` | после коммита | уведомления |
| `post-checkout`, `post-merge` | после смены ветки, слияния | установить зависимости, если изменился lock-файл |
| `pre-rebase` | перед [rebase](https://llmdocs.ru/wiki/merge-rebase.md) | запрет переписывать опубликованные ветки |
| `pre-push` | перед отправкой | быстрые тесты |

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

```bash
#!/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](https://llmdocs.ru/wiki/github.md) и [GitLab](https://llmdocs.ru/wiki/gitlab.md) произвольные серверные хуки обычно недоступны (GitLab разрешает их на собственной установке); вместо них используют правила защиты веток, push rules и вебхуки, а проверки — в CI.

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

- **pre-commit** — фреймворк на Python с тысячами готовых хуков; конфигурация в `.pre-commit-config.yaml`, каждое средство ставится в изолированное окружение. Работает для любых языков.[3]
- **husky** — популярный выбор в экосистеме JavaScript, хуки хранятся в `.husky/`; часто в паре с `lint-staged`, который проверяет только изменённые файлы.[4]
- **lefthook** — быстрый менеджер на Go с параллельным запуском и конфигурацией в YAML.[5]

```yaml
# .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](https://llmdocs.ru/wiki/ruff.md) проверяет Python-код, а gitleaks ищет случайно добавленные ключи и пароли.

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

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

## Ограничения

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

## См. также

- [Git](https://llmdocs.ru/wiki/git.md)
- [CI/CD](https://llmdocs.ru/wiki/ci-cd.md)
- [Pull request / Merge request](https://llmdocs.ru/wiki/pull-request.md)
- [GitHub Actions](https://llmdocs.ru/wiki/github-actions.md)

## Источники

1. [Git Documentation — githooks](https://git-scm.com/docs/githooks)
2. [Pro Git — Customizing Git: Git Hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)
3. [pre-commit — framework for managing git hooks](https://pre-commit.com/)
4. [husky](https://typicode.github.io/husky/)
5. [lefthook](https://github.com/evilmartians/lefthook)
6. [Conventional Commits](https://www.conventionalcommits.org/)
