Настройка Git Hooks (pre-commit, pre-push) для проверки кода

Дефекты и стилевые расхождения проще не допустить, чем искать их на ревью и в релизе. Мы настраиваем Git Hooks под ключ: проверки запускаются автоматически на каждом этапе работы с кодом, до того как правка попадёт в общий репозиторий. Команда получает единые правила игры и заметно меньше возвратов на доработку.
Часто задаваемые вопросы

Git Hooks: почему проверки кода пропускают дефекты

Правила проверки почти всегда описаны: есть договорённость о стиле, набор тестов, статический анализ в общем конвейере сборки. Но в репозиторий всё равно уходят незакрытые ошибки, спорный стиль и тесты, которые падают на следующем шаге. Причина одна — проверки стоят слишком далеко от момента, когда код пишется.

Типовая картина: pre-commit hook не настроен, pre-push молчит, и первый сигнал о проблеме приходит из общей сборки спустя десятки минут после отправки. Разработчик к этому времени переключился на другую задачу, контекст потерян, а сломанная сборка блокирует ветку целиком — не только автора последнего коммита.

Вторая причина — хуки живут на машине того, кто их однажды настроил. Свежий клон не получает ни одного скрипта, пока их не установят руками, поэтому «у меня всё проходит» и «у тебя не собирается» существуют одновременно, а качество кода в репозитории держится на дисциплине, а не на автоматике.

Git позволяет держать git hooks прямо в репозитории и подключать их через общую конфигурацию — тогда проверки перед коммитом одинаковы у всей команды, включая новых участников. Разбираем, как это настраивается и что стоит проверять автоматически, а что оставить ревью.

Что перехватывают проверки на каждом этапе работы с кодом

Первый рубеж — pre-commit: он срабатывает до того, как правка станет частью истории, и работает только по изменённым файлам, поэтому укладывается в секунды. На этом шаге отсекается то, что не требует думать: конфликтные маркеры, отладочные вставки, случайно попавшие ключи и пароли, несогласованный стиль и порядок импортов. Автопроверка стиля кода убирает целый класс споров: форматирование перестаёт быть предметом обсуждения на ревью, потому что его приводит к единому виду инструмент, а не вкус конкретного инженера.

Второй рубеж — pre-push, проверки на этапе разработки перед отправкой ветки. Здесь запускается то, что дольше: сборка, проверка типов, быстрые тесты, валидация схем данных и миграций. Дефект отсекается, пока автор ещё держит в голове логику своих изменений, — правка занимает минуты вместо разбора через сутки, когда контекст уже утерян. Именно смещение обнаружения внутрь рабочего процесса даёт раннее обнаружение дефектов без накладных расходов на передачу задачи между людьми.

Серверная проверка остаётся последним рубежом и ловит то, что обошло локальные хуки: обход флагами, устаревшая ветка, слияние без прогонов. Единые правила команды работают, когда они описаны в конфигурации репозитория и применяются одинаково у всех, включая новых участников, — тогда ревью начинается с логики и архитектуры, а не с отступов и опечаток. Доля замечаний по мелочам в обсуждениях падает заметно, и то же время ревьюера уходит на то, что действительно требует человека.

Стоимость исправления ошибки растёт нелинейно по мере удаления от момента правки: секунды на локальном запуске, несколько итераций ревью при обнаружении в общей ветке, откат и разбор последствий — если дефект доехал до выката. Поэтому проверки стоит расставлять по возрастанию тяжести: мгновенное — до коммита, тяжёлое — перед отправкой, полный набор — на сервере. Работает не количество хуков, а покрытие ими тех путей, где дефекты действительно появляются.

Варианты внедрения проверок: клиентские, серверные, гибридные

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

Вариант Когда подходит Ограничения
Клиентские хуки (pre-commit, pre-push) Нужен быстрый отклик на форматирование и грубые ошибки до отправки Обходятся флагом пропуска хуков, зависят от локального окружения и версий анализаторов
Серверные проверки (pre-receive, update) Нужны неотключаемые правила: формат сообщений коммитов, запрет правки защищённых веток Срабатывают уже после отправки — автор видит отказ поздно, исправление требует новых коммитов
Проверки в конвейере сборки Полный прогон тестов, анализаторов кода и сборка на чистом окружении Обратная связь приходит через минуты и делит очередь задач с остальными сборками
Гибридная схема проверок Нужны одновременно быстрый отклик и барьер, который нельзя обойти Требует синхронизации конфигураций и версий анализаторов между уровнями

Серверные проверки в GitLab подключаются как скрипты на стороне репозитория и срабатывают до применения изменений, поэтому не зависят от настроек машины и версий инструментов у автора.

На практике рабочая схема — гибридная. Клиентские хуки берут то, что должно падать за секунды: форматирование, быстрые анализаторы кода, проверку сообщения коммита. Серверные — то, что обходить нельзя: защищённые ветки и правила именования. Конвейер сборки оставляет за собой полный прогон тестов там, где нет локальных артефактов и кэша разработчика.

Условие работоспособности гибрида — единый конфигурационный файл анализаторов для всех трёх уровней. Иначе локальный прогон проходит, а серверный падает на тех же строках, и доверие к проверкам пропадает быстрее, чем они окупаются.

Как мы внедряем Git Hooks: этапы инженерной работы

Хуки встраиваются в уже работающий процесс, а не заменяют проверки на сервере. Барьер ставим там, где ошибку дешевле всего исправить — на машине разработчика, до отправки в общую ветку. Поэтому работа идёт от аудита текущих правил до регламента, который команда дальше поддерживает сама.

  1. Аудит правил проверки. Разбираем, что уже ловит сборочная линия и какие ошибки доходят до ручной проверки. По этому списку выбираем проверки для локального барьера — дублировать всё подряд незачем.
  2. Выбор точки контроля. Форматирование, линтер и поиск ключей в изменениях — на pre-commit; типы и тесты затронутых модулей — на pre-push, чтобы коммит не ждал.
  3. Настройка хуков. Конфиг живёт в репозитории и ставится одной командой: правила приезжают вместе с кодом и одинаковы у всех, включая новых участников.
  4. Тестирование проверок. Прогоняем реальные сценарии: сломанный формат, ключ в изменённом файле, ветка с несколькими коммитами, переименование. Смотрим и на скорость — медленный хук начинают обходить.
  5. Порядок внедрения. Сначала режим предупреждений, потом блокировка: резкий переход даёт волну обходов и обесценивает проверку.
  6. Передача регламентов. Отдаём документацию: как добавить или изменить правило, когда обход оправдан, что делать при сбое хука на чужой машине.

Конфигурации хуков, схемы проверок и регламенты для команды

Передаём не описание, а работающий набор файлов в репозитории. Каждое правило проверки живёт рядом с кодом, версионируется вместе с ним и одинаково срабатывает на машине разработчика и в сборочном окружении — правила не расходятся между машинами и не теряются при обновлении.

  • Конфигурации хуков — готовые правила для pre-commit и pre-push: форматирование, статический анализ, проверка имени ветки и сообщения коммита, быстрый набор тестов.
  • Единый установщик — одна команда после клонирования подключает проверки каждому. Иначе часть команды работает без них и узнаёт о правилах только при слиянии.
  • Схема проверок — какой хук что запускает, что блокирует коммит, что даёт предупреждение, сколько длится этап. Долгие проверки переносим на сервер, чтобы коммит оставался быстрым.
  • Политики доступа к репозиторию — кто может менять конфигурацию хуков и список исключений, защита основной ветки, дублирование ключевых проверок на стороне сервера.
  • Инструкция по исключениям — как оформить пропуск для файла или правила: где живёт список, какое обоснование нужно, кто согласует и когда пересматриваем.
  • Документация для команды — что делать при срабатывании проверки, как исправить типовые ошибки, как обновить набор правил.
  • Регламент сопровождения — периодичность обновления набора, ответственный, порядок добавления новых проверок.

Приёмка идёт на вашей ветке: показываем срабатывание проверки, обход по инструкции и прохождение после исправления.

Кейс: как автоматические проверки сократили дефекты до релиза

Распределённая команда из четырнадцати инженеров в четырёх часовых поясах вела монолит и несколько сервисов в одном репозитории на Git. Ветки жили по два-три дня, и правки, затронувшие общий модуль, приезжали на ревью к человеку, который в этот момент спал. Проверки ловили расхождения в стиле и забытые отладочные выводы уже после слияния — то есть тогда, когда за них брался тестировщик, а не автор кода.

Что настроили

Хук на коммит приводил форматирование к общему виду, прогонял линтер по изменённым файлам и обрывал коммит, если в диффе находил ключи, токены доступа или файлы окружения. Хук на отправку запускал тесты затронутых модулей, проверял, что сообщение коммита связано с задачей в трекере, и запрещал прямой пуш в защищённые ветки. Каждая проверка работает только по изменённым путям — прогон укладывается в десятки секунд и не тормозит работу.

Что изменилось

Доля дефектов, которые находили до релиза, выросла с 62% до 91%: расхождения в логике стали видны на машине автора, а не на стенде. Среднее время код-ревью сократилось с суток до пяти-шести часов — из ревью ушли споры о форматировании, и на одну правку остаётся один-два замечания по существу вместо шести. Возвратов к автору стало втрое меньше, потому что часть их отсекалась ещё до создания ветки.

Обход проверок мы оставили возможным — только через явный флаг, и такие коммиты попадают в отчёт для руководителя. За аварийные исправления команда заплатила предсказуемостью: нарушения видны, а не растворяются в истории.

Чем pre-commit отличается от pre-push и что выбрать

Это не альтернативы, а две разные точки контроля с разным объёмом данных. pre-commit видит только подготовленные к коммиту файлы и стоит секунды — туда ставят форматирование, линтер, поиск ключей и паролей, запрет на большие бинарные файлы. pre-push смотрит на все коммиты отправляемой ветки, поэтому там уже уместны проверка типов, тесты затронутых модулей и сборка.

Главное ограничение — терпение разработчика. Если pre-commit выполняется дольше нескольких секунд, его начинают обходить флагом --no-verify, и точка контроля превращается в формальность. pre-push срабатывает реже и допускает десятки секунд: цена ошибки выше, а полная картина ветки недоступна на этапе одиночного коммита.

Параметр pre-commit pre-push
Точка контроля перед созданием коммита перед отправкой ветки
Область проверки подготовленные файлы все коммиты ветки
Что запускают форматирование, линтер, поиск секретов типы, тесты, сборка
Скорость секунды десятки секунд
Нагрузка на разработчика минимальная, часто правит код сам заметная, но редкая

Выбор обычно не бинарный: pre-commit держит чистоту истории и не даёт мусору накапливаться, pre-push ловит то, что требует полной картины — расхождение типов между модулями, падение тестов на стыке изменений. Правило простое: тяжесть проверки растёт вместе с моментом срабатывания. Всё, что дольше, выносится на сервер, где обход уже невозможен.

Практика настройки — общий набор правил в репозитории, чтобы одинаковые проверки работали у всей команды без ручной установки. Если нужно, разберём вашу ветку разработки и предложим раскладку проверок по точкам.

Частые технические сомнения по внедрению проверок

Перед внедрением проверок инженеры поднимают одни и те же вопросы: не замедлят ли хуки работу, легко ли их обойти, как это уживается с конвейером сборки. Ниже — прямые ответы.

Проверки замедлят каждый коммит?

Проверка идёт только по изменённым файлам из индекса, а не по всему репозиторию, и результаты кэшируются между запусками. Форматирование и линт на десятках файлов занимают секунды, а тяжёлые шаги — тесты, сборка — выносятся на предварительный push или в конвейер.

Хук всё равно обойдут флагом?

Да, локальный хук обходится одной опцией, и это нормально: он нужен для быстрой обратной связи, а не как средство контроля. Гарантию даёт дублирование тех же правил обязательным шагом сборки плюс защита веток от прямого push — тогда обход хука не влияет на качество кода в ветке.

Как не дублировать правила в конвейере?

Правила лежат в одном конфиге внутри репозитория и вызываются двумя профилями: быстрым локальным и полным в сборке. Набор проверок общий, отличаются глубина и объём, поэтому расхождение «локально прошло, в сборке упало» исчезает.

У нас в репозитории несколько языков

Общие шаги — форматирование, поиск секретов, проверка имён — работают поверх всех каталогов. Языковые проверки подключаются по маскам путей, а окружения изолируются контейнерами, чтобы зависимости разных языков не конфликтовали.

Кто поддерживает проверки дальше?

Конфигурация живёт в репозитории и меняется через обычное ревью, как код. Мы передаём регламент обновления правил и разбор частых ошибок, чтобы команда расширяла проверки сама, без внешней поддержки.

Обсудим вашу задачу: что подготовить к разговору

Чтобы оценка и план работ опирались на факты, а не на предположения, к первому разговору достаточно нескольких вводных. Готовить пакет документов заранее не нужно — часть данных соберём вместе, но чем точнее исходная картина, тем короче путь от обсуждения задачи до старта работ.

  • Репозитории: сколько их, это монорепозиторий или набор отдельных, какие ветки защищены от прямых коммитов.
  • Стек по языкам и то, что уже проверяется на сервере непрерывной интеграции — линтеры, форматирование, статический анализ, тесты.
  • Правила ветвления: порядок слияния, обязательные проверки перед мержем, у кого есть право их обходить.
  • Способ доставки хуков на машины разработчиков: общий каталог внутри репозитория, скрипт инициализации или менеджер пакетов.
  • Разделение проверок между pre-commit и pre-push: чувствительность к времени ожидания у разработчика против полноты проверяемых правил.
  • Ограничения по доступам и политике безопасности: нужен ли режим без внешних зависимостей, есть ли закрытые реестры пакетов.
  • Состав команды и зоны ответственности: кто владеет стандартами кода и кто будет сопровождать правила после сдачи.

Дальше согласуем целевую конфигурацию, раскатываем её на пилотный репозиторий и замеряем время проверок и долю блокируемых коммитов. Получив эти цифры, фиксируем план работ по остальным репозиториям и порядок подключения команды: старт занимает дни, а не недели. Опишите задачу и пришлите то, что есть под рукой, — вернёмся с оценкой и планом.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    815
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139