Хуки в Git на практике: что проверять до коммита
Хук Git может остановить коммит с ошибкой форматирования или запустить быстрые тесты, но сам по себе не заменяет проверку качества кода. Разбираем, где хранить проверки, что запускать локально и почему окончательный контроль всё равно нужен в CI.

Хук Git остановит коммит, если проверка не прошла, но локальный скрипт легко обойти, а тесты могут проверить не тот код, который попадёт в коммит. В Git 2.45 и новее разумная схема такая: быстрые проверки запускаются локально, общие правила лежат в репозитории, а обязательный контроль выполняется на сервере или в CI.
Сначала решите, что должен делать хук
Хук — это программа, которую Git запускает при определённом событии: например, перед коммитом или отправкой изменений. Практическое правило простое: проверка должна быть быстрой, предсказуемой и понятной по ошибке. Если она занимает несколько минут или требует доступа к внешнему сервису, разработчики начнут искать способ её пропустить.
Для локального pre-commit подходят проверки, которые укладываются в привычный цикл работы: форматирование, пробелы в изменённых строках, короткий набор тестов. Полный набор тестов, проверку сборки и правила, которые нельзя обойти перед слиянием, лучше закрепить в CI.
Хук — не замок на двери. Это раннее предупреждение: оно экономит время, но не заменяет контроль на стороне команды.
Термин: индекс — подготовленная к коммиту область Git. Коммит сохраняет содержимое индекса, а не все изменения, которые вы видите в рабочей папке.
Три места для проверок — и три разных задачи
| Подход | Что даёт | Цена и ограничение | Когда выбирать |
|---|---|---|---|
Хук в .git/hooks | Быстро подключается на одном компьютере | Папка обычно не попадает в коммит; коллеги не получат настройку вместе с кодом | Личная проверка или короткий эксперимент |
| Общий каталог хуков в репозитории | Скрипты можно ревьюить и менять вместе с проектом | Каждому клону нужно настроить Git; остаётся возможность пропуска | Командные быстрые проверки |
| CI или серверная проверка | Результат видит команда; правило можно сделать обязательным для слияния | Проверка запускается позже и требует настроенной инфраструктуры | Тесты, сборка и требования, важные для выпуска |
Git не копирует обычные локальные хуки при клонировании репозитория. Поэтому каталог `.git/hooks` удобен для личных скриптов, но не для командного соглашения. Для общего набора можно хранить исполняемые файлы в отслеживаемом каталоге, например `.githooks`, и указать Git использовать его. Настройку придётся выполнить каждому участнику проекта.
Практический пример: проверить подготовленные изменения
Для проверки пробелов в изменённых строках не нужна сторонняя утилита: Git умеет выполнить её сам. Создайте в корне проекта файл `.githooks/pre-commit`:
#!/bin/sh
git diff --cached --check
Затем укажите Git каталог хуков:
git config --local core.hooksPath .githooks
В Unix-подобной системе сделайте файл исполняемым: chmod +x .githooks/pre-commit. На Windows учитывайте настройки Git for Windows и способ, которым файл попал в репозиторий: проверьте запуск хука на той же платформе и в том же окружении, где работает команда. Не считайте настройку готовой, пока не проверили её на чистом клоне.
git diff --cached --check проверяет именно подготовленный diff. Если Git находит проблему с пробелами, коммит прекращается; исправьте строки, снова добавьте нужные файлы в индекс и повторите коммит. Проверка не форматирует код и не запускает тесты — её задача уже и яснее.
Что чаще всего ломается
Проверка видит не тот набор изменений
Тесты, запущенные из хука, обычно читают файлы рабочей папки. Но коммит содержит индекс, и часть незакоммиченных изменений может в него не попасть. Тогда тесты пройдут на одном содержимом, а в коммит попадёт другое. Для короткой проверки пробелов удобно использовать staged diff; тесты запускайте только если команда понимает это ограничение или проверка отдельно собирает состояние индекса.
Хук не запускается у коллеги
Проверьте, что файл есть в клоне, путь в core.hooksPath совпадает с именем каталога, а файл исполняемый там, где это требуется. Уточнить текущую настройку можно командой git config --show-origin --get core.hooksPath. Если команда ничего не вывела, для этого параметра нет значения в проверяемой конфигурации.
Локальная проверка стала тормозить
Замерьте время запуска на обычном ноутбуке команды, а не только на мощной рабочей станции. Разделите проверки по стоимости: короткие оставьте перед коммитом, тяжёлые перенесите в CI или запускайте отдельной командой. Не делайте хук сетевой зависимостью без необходимости: недоступный сервис не должен неожиданно блокировать повседневную работу.
Проверку обходят
Клиентский хук не обеспечивает защиту: Git позволяет пропустить некоторые проверки специальными параметрами команд. Это полезно знать для диагностики и аварийных случаев, но значит, что локальный хук нельзя считать единственным способом соблюсти правило. Если ошибка должна блокировать слияние или выпуск, проверяйте её в CI и настройте обязательное прохождение соответствующей проверки.
Как выбрать место для каждой проверки
- Личная привычка — локальный хук в `.git/hooks`: например, напоминание или действие только для вашей среды.
- Правило команды, которое должно срабатывать рано — версия хука в репозитории и документированная настройка для каждого клона. Проверьте её на macOS, Linux и Windows, если команда работает на всех трёх системах.
- Условие для слияния — CI или серверная проверка. Локальный хук может дублировать быстрый тест, но не заменяет обязательный контроль.
Для выбора важны не только секунды выполнения, но и стоимость ложного отказа: кто разберётся с ошибкой, можно ли повторить проверку без доступа к сети и будет ли одинаковый результат на разных машинах. Хороший хук выводит причину отказа и следующий шаг, а не просто завершает работу с ненулевым кодом.
Что делать дальше
Начните с одной проверки, которую легко объяснить и повторить. Добавьте её в каталог хуков, настройте на чистом клоне и попросите коллег проверить на их операционных системах. Затем перенесите обязательные тесты и сборку в CI. В рабочем проекте следите за временем локального хука, долей ошибок окружения и тем, совпадают ли локальные проверки с теми, что блокируют слияние.
Примеры выше рассчитаны на Git 2.45 и совместимые версии Git 2.x; перед внедрением сверяйте поведение с документацией используемой версии.
Тест и проверочная: Быстрые ответы с объяснением, почему остальные варианты неверны
Спросить за 10 ₽Источники: Git — githooks, Git — core.hooksPath
Частые вопросы
Почему хук не запускается после клонирования репозитория?
Можно ли заставить Git всегда запускать локальный хук?
Что проверяет `git diff --cached --check`?
Можно ли запускать в `pre-commit` полный набор тестов?
Что делать, если хук работает у коллег, но не у меня?
Стоит ли добавлять в хук проверку, которая обращается к сети?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.