Тур по Git
Продвинутый Git / Урок 5.6

Git-хуки — Автоматизация

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

Как работают хуки

Хуки находятся в директории .git/hooks/. При инициализации репозитория Git создаёт примеры хуков с расширением .sample. Удалите расширение, чтобы активировать их:

.git/hooks/
  pre-commit.sample     →  переименуйте в pre-commit для активации
  commit-msg.sample     →  переименуйте в commit-msg для активации
  pre-push.sample       →  переименуйте в pre-push для активации

Хуки могут быть написаны на любом языке — Bash, Python, Ruby, Node.js — при условии, что файл является исполняемым.

Наиболее полезные хуки

pre-commit

Запускается перед созданием коммита. Используйте для:

  • Линтинг — проверка стиля кода
  • Форматирование — автоформатирование подготовленных файлов
  • Обнаружение секретов — предотвращение коммита API-ключей
#!/bin/sh
# .git/hooks/pre-commit

# Запуск линтера на подготовленных файлах
npm run lint --staged
if [ $? -ne 0 ]; then
  echo "Lint failed. Fix errors before committing."
  exit 1
fi

Если скрипт завершается с ненулевым кодом, коммит отменяется.

commit-msg

Запускается после написания сообщения коммита. Используйте для проверки формата сообщения:

#!/bin/sh
# .git/hooks/commit-msg

# Требовать, чтобы сообщения коммитов начинались с префикса типа
if ! grep -qE "^(feat|fix|docs|style|refactor|test|chore):" "$1"; then
  echo "Commit message must start with: feat:, fix:, docs:, etc."
  exit 1
fi

pre-push

Запускается перед отправкой на удалённый репозиторий. Используйте для:

  • Запуска полного набора тестов
  • Предотвращения отправки в защищённые ветки
#!/bin/sh
# .git/hooks/pre-push

# Запуск тестов перед отправкой
npm test
if [ $? -ne 0 ]; then
  echo "Tests failed. Push aborted."
  exit 1
fi

Инструменты для хуков

Управление хуками вручную утомительно. Популярные инструменты помогают:

  • Husky (JavaScript) — управление хуками через package.json
  • pre-commit (Python) — мультиязычный фреймворк хуков
  • lefthook (Go) — быстрый, языконезависимый менеджер хуков

Пример с Husky:

{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  }
}

Клиентские и серверные хуки

ТипГде выполняетсяПримеры
КлиентскиеМашина разработчикаpre-commit, commit-msg, pre-push
СерверныеGit-серверpre-receive, post-receive, update

Серверные хуки обеспечивают правила, которые невозможно обойти. Клиентские хуки можно пропустить с помощью --no-verify.

Типичные сценарии

  • Линтинг при коммите — раннее обнаружение проблем со стилем
  • Запуск тестов при пуше — предотвращение попадания сломанного кода на удалённый репозиторий
  • Проверка сообщений коммитов — поддержание чистой и удобной для поиска истории
  • Автоформатирование — применение Prettier/Black к подготовленным файлам
  • Проверка имён веток — обеспечение соглашений об именовании вроде feature/, fix/

Ограничения

  • Хуки не отправляются вместе с репозиторием (они находятся в .git/hooks/)
  • Разработчики должны настраивать их локально (или использовать инструменты вроде Husky)
  • Клиентские хуки можно обойти с помощью git commit --no-verify