0052 — pre-commit
Утилита pre-commit изменила моё представление о работе с Git и статическими анализаторами. Какую же задачу она решает?
pre-commit
решает задачу проверки кода перед его фиксацией в Git.
Типы проверок бывают разные. Например, вы можете включить автоматическое удаление висячих пробелов в концах строк, автоматическую вставку пустой строки в конце файлов, принудительное использование пробелов или табуляции в определённых типах файлов и многое другое, блокировку добавления в индекс файлов с размером больше указанного.
«Из коробки» pre-commit
уже имеет несколько готовых правил, но ещё больше можно получить путём установки различных расширений. Для начала посмотрите, какие хуки хранятся в репозитории pre-commit/pre-commit-hooks.
Установка
pre-commit
написан на Python. По этой причине для его установки рекомендуется использовать PIP. Я советую добавить pre-commit
в список зависимостей Python для проекта и установить их в виртуальное окружение.
Добавьте в
REQUIREMENTS
строку с названием пакета:pre-commit
Активируйте виртуальное окружение Python:
source .venv/bin/activate
Установите пакеты, указанные в
REQUIREMENTS
:pip install -r REQUIREMENTS
Настройка
Создайте в корневом каталоге проекта файл
.pre-commit-config.yaml
с примерно таким содержимым:--- repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - id: check-merge-conflict
Примечание: эти настройки я использую для репозитория, в котором хранится исходный код сайта.
Инициализируйте
pre-commit
и хуки Git:git-commit install --install-hooks
На этом всё.
Использование
Теперь, когда вы попытаетесь сделать любой коммит в вашем репозитории, будет происходить следующее:
- Срабатывание хука Git, запускающего
pre-commit
. - Запуск обработчиков, необходимые для выполнения настроек, указанных в
.pre-commit-config.yaml
.
Если на каком-то из этапов в хотя бы один файл будут внесены изменения, pre-commit
прервёт создание коммита. Например, прямо сейчас в исходном коде этого файла я оставил несколько висячих пробелов. Попробую закоммитить изменения:
Head: main Update pre-commit settings
Merge: origin/main Update pre-commit settings
Staged changes (1)
new file content/posts/0052-pre-commit.md…
Ой!
GitError! Git failed [Type `$' for details]
Head: main Update pre-commit settings
Merge: origin/main Update pre-commit settings
Unstaged changes (1)
modified content/posts/0052-pre-commit.md…
Staged changes (1)
modified content/posts/0052-pre-commit.md…
Во время запуска pre-commit
файл с этим постом был изменён. По этой причине Git отменил создание коммита. Зато все висячие пробелы были удалены, да и пустая строка в конце файла тоже добавлена. Посмотрим, что там выдал Git (я нажму [$] в буфере magit):
0 git … add -u -- content/posts/0052-pre-commit.md
1 git … commit --
check yaml...........................................(no files to check)Skipped
fix end of files.........................................................Passed
trim trailing whitespace.................................................Failed
- hook id: trailing-whitespace
- exit code: 1
- files were modified by this hook
Fixing content/posts/0052-pre-commit.md
check for merge conflicts................................................Passed
Из этого вывода сразу понятно, где споткнулся pre-commit
и какие изменения он сделал. Это почти EditorConfig, только от которого нельзя отказаться. Лучше всего эти инструменты работают вместе.
Ещё pre-commit
можно запускать без создания коммита. Достаточно добавить файлы в индекс и выполнить команду:
pre-commit run --all