Перейти к содержанию

Git Hooks: Автоматизация действий

Git Hooks — это скрипты, которые автоматически выполняются при определенных событиях в репозитории (коммит, пуш, merge и т.д.). Они позволяют автоматизировать проверки, тесты, форматирование кода и другие задачи.

Где хранятся хуки?

Хуки находятся в папке .git/hooks вашего репозитория. По умолчанию там лежат примеры с расширением .sample. Чтобы активировать хук, нужно: 1. Удалить .sample из имени файла. 2. Сделать скрипт исполняемым (chmod +x).

Типы хуков

Локальные хуки (выполняются на стороне клиента)

  • pre-commit — выполняется перед созданием коммита. Идеально для проверок кода (линтеры, тесты).
  • prepare-commit-msg — после открытия редактора сообщения коммита, но до ввода текста.
  • commit-msg — после ввода сообщения коммита. Можно проверить формат сообщения.
  • post-commit — сразу после коммита. Для уведомлений или логирования.
  • pre-push — перед отправкой на сервер. Для запуска тестов перед пушем.

Серверные хуки (выполняются на удаленном сервере)

  • pre-receive — при получении пуша на сервере.
  • update — аналогично pre-receive, но вызывается для каждой ветки отдельно.
  • post-receive — после успешного пуша. Для деплоя, уведомлений.

Примечание: Серверные хуки настраиваются на стороне сервера (GitHub Enterprise, GitLab, свой Git-сервер). На GitHub.com и GitLab.com их нельзя использовать напрямую — вместо этого используйте CI/CD.

Примеры хуков

Pre-commit: Проверка кода перед коммитом

Создайте файл .git/hooks/pre-commit:

#!/bin/bash

# Проверить, есть ли изменения в staged
echo "Запуск pre-commit хука..."

# Проверить наличие отладочных console.log
if git diff --cached | grep -q "console.log"; then
    echo "❌ Ошибка: найден console.log в коде!"
    echo "Удалите отладочный вывод перед коммитом."
    exit 1
fi

# Запустить линтер (если установлен)
if command -v eslint &> /dev/null; then
    echo "Запуск ESLint..."
    eslint . --fix
    if [ $? -ne 0 ]; then
        echo "❌ ESLint нашел ошибки!"
        exit 1
    fi
fi

# Проверить форматирование (Prettier)
if command -v prettier &> /dev/null; then
    echo "Проверка форматирования..."
    prettier --check "**/*.{js,ts,css,md}"
    if [ $? -ne 0 ]; then
        echo "❌ Файлы не отформатированы!"
        echo "Запустите: npm run format"
        exit 1
    fi
fi

echo "✅ Все проверки пройдены!"
exit 0

Сделайте исполняемым:

chmod +x .git/hooks/pre-commit

Теперь при каждом git commit будут запускаться проверки. Если хук вернет код ошибки (не 0), коммит будет отменен.

Commit-msg: Проверка формата сообщения

Файл .git/hooks/commit-msg:

#!/bin/bash

COMMIT_MSG_FILE=$1
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")

# Проверка: сообщение должно начинаться с заглавной буквы и быть не короче 10 символов
if ! echo "$COMMIT_MSG" | grep -qE "^[A-Z].{9,}"; then
    echo "❌ Ошибка: Сообщение коммита должно начинаться с заглавной буквы и быть длиннее 10 символов."
    echo "Пример: 'Добавить новую функцию авторизации'"
    exit 1
fi

# Проверка на наличие номера задачи (опционально)
# if ! echo "$COMMIT_MSG" | grep -qE "#[0-9]+"; then
#     echo "⚠️  Предупреждение: Рекомендуется указать номер задачи (например, #123)"
# fi

exit 0

Pre-push: Запуск тестов перед отправкой

Файл .git/hooks/pre-push:

#!/bin/bash

echo "🚀 Запуск тестов перед push..."

# Запустить тесты
npm test
if [ $? -ne 0 ]; then
    echo "❌ Тесты не прошли! Пуш отменен."
    exit 1
fi

# Запустить сборку
npm run build
if [ $? -ne 0 ]; then
    echo "❌ Сборка не удалась! Пуш отменен."
    exit 1
fi

echo "✅ Тесты и сборка пройдены!"
exit 0

Управление хуками через Husky (для Node.js проектов)

Ручное управление хуками неудобно в команде. Инструмент Husky автоматизирует этот процесс.

Установка Husky

npm install husky --save-dev
npx husky init

Это создаст папку .husky с настройками.

Добавить хук

npx husky add .husky/pre-commit "npm test"
npx husky add .husky/pre-push "npm run build"

Теперь хуки будут работать у всех разработчиков после установки зависимостей (npm install).

Интеграция с lint-staged

Для запуска проверок только на измененных файлах:

npm install lint-staged --save-dev

В package.json:

{
  "lint-staged": {
    "*.js": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{css,md,json}": [
      "prettier --write"
    ]
  },
  "scripts": {
    "prepare": "husky install"
  }
}

Создайте хук .husky/pre-commit:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged

Отключение хуков

Временное отключение всех хуков:

git commit --no-verify -m "Сообщение"
# или кратко
git commit -n -m "Сообщение"

Осторожно: Используйте только в экстренных случаях, когда понимаете последствия.

Лучшие практики

  1. Хуки должны быть быстрыми. Никто не будет ждать 5 минут перед коммитом.
  2. Не ломайте рабочий процесс. Хуки должны помогать, а не мешать.
  3. Автоматически исправляйте, если возможно. Например, prettier --fix лучше, чем просто проверка.
  4. Документируйте требования. Новые разработчики должны знать о хуках.
  5. Используйте shared hooks. В больших проектах храните хуки в отдельном репозитории и подключайте при установке проекта.

Частые проблемы

Хук не выполняется

  • Проверьте, что файл исполняемый: chmod +x .git/hooks/pre-commit.
  • Убедитесь, что нет расширения .sample.
  • Проверьте путь к интерпретатору в первой строке (#!/bin/bash).

Хук падает с ошибкой

  • Добавьте отладочный вывод (echo) для поиска проблемы.
  • Проверьте, что все команды доступны в PATH.
  • Убедитесь, что хук возвращает exit 0 при успехе.

Назад: Подмодули → | Далее: Переписывание истории →