Хуки git: почему коммит не проходит
Обновлено 31 июля 2026 г.
Ты набираешь git commit, а вместо нового коммита в терминале появляется сообщение от линтера или проверки, и коммит не создан. Сработал хук - скрипт, который git запускает сам на определённое событие.
Событий много: перед созданием коммита, после него, перед git push, перед git rebase. Скрипты лежат в каталоге .git/hooks внутри репозитория, по одному файлу на событие. Если файл есть и он исполняемый, git его запускает; когда скрипт завершается с ненулевым кодом, git отменяет операцию.
Вот как это выглядит. Хук pre-commit прогоняет тесты и не пускает коммит, пока они падают:
$ git commit -m "добавил поиск"
tests failed, commit abortedДальше ничего. Строки о новом коммите нет, а подготовленные изменения так и остаются в индексе, готовые к следующей попытке. Текст tests failed, commit aborted напечатал сам скрипт; git от себя не добавил ничего - просто не создал коммит.
Второй по частоте хук - commit-msg. Он получает файл с твоим сообщением и решает, годится ли оно. Например, требует префикс, как в сообщении коммита:
$ git commit -m "update app"
commit message must start with feat:, fix:, docs: or chore:Разница между двумя: pre-commit смотрит на сами изменения (формат, тесты, забытый console.log), а commit-msg - только на текст сообщения.
Хуки не уезжают вместе с коммитом
Это и путает чаще всего. Каталог .git/hooks - часть служебной папки .git, а её содержимое git не версионирует и на сервер не отправляет. Твои хуки остаются на твоей машине; у коллеги их не будет, даже если он склонировал тот же репозиторий. Поэтому команды раздают хуки отдельным инструментом: pre-commit в проектах на Python, husky в проектах на Node. Инструмент сам кладёт скрипты в .git/hooks при установке, а его конфиг лежит в репозитории и приезжает всем.
Прочитать и, если надо, обойти
Первым делом читай вывод сверху вниз: там сказано, что именно не устроило хук - формат файла, длина сообщения, упавший тест. Часто хук сам чинит проблему (переформатировал файл) и просит повторить git commit.
Обойти проверку можно флагом --no-verify:
$ git commit --no-verify -m "fix: срочная правка"Он пропускает pre-commit и commit-msg целиком. Это аварийный выход, а не привычка: проверку повесили не просто так, и коммит, который не прошёл бы её локально, всё равно упрётся в ту же проверку на CI, уже на глазах у всей команды.
Частые ошибки
Считать, что раз хук сработал у тебя, значит он есть у всех. Хуки локальные; без общего инструмента раздачи у каждого свой набор, и «у меня проходит» ничего не гарантирует.
Привыкать к --no-verify. Один обход в аврал - нормально. Постоянный означает, что проверка мешает, и чинить надо её или свой код, а не глушить флагом.
Где это в учебнике
Глава 7. Как git используют в командах. Рядом пригодятся git commit и сообщение коммита.