⭐ Команды и проверки перед коммитом. pre-commit
Для меня это «game-changer»
Зачем использовать pre-commit хуки?
- Чтобы случайно не залить в репозиторий сломанный код / данные
- Чтобы заливаемый код всегда был отформатирован в одном стиле
- Чтобы соблюдать договоренности в духе «в файле Х мы не используем Y» (я иногда кастомлю
assertфункции и не хочу, чтобы из-за мышечной памяти я случайно заиспользовал оригинальныйassertтам, где не нужно) - Для исполнения любых других команд, которые сочтём нужными / экономящими наше время
База
В git-е можно подвязать свои команды на различные события (вроде pre-commit, commit-msg, post-commit, pre-merge-commit, pre-push и пр.)
Это были бы одноименные файлы-скрипты в .git/hooks/
Но я с ними никогда не работал и, честно говоря, разбираться не хочу :/
Я просто однажды наткнулся на удобный инструмент-фреймворк «pre-commit» и с тех пор его использую
Примеры задач, для которых я использую pre-commit
Для автоформатирования (yaml, json, toml, gdscript, python, python-stubs, c++, c#, go, и пр.) (btw, форматтеры отчасти являются проверками — они падают с ошибкой при встрече кода с невалидным синтаксисом)
Для линтинга (gdlint, cpplint, ruff check, yamllint, ty check, pyright, mypy)
Для соблюдения договорённостей
— Запрещаю коммитить, если где-то есть строка с
noсheckin(оставляю такие отметки, чтобы 100% перед коммитом вернуться в какую-то часть кода) (подсмотрел у Jonathan Blow) (в vscodevim забиндил ctrl+n для мгновенной вставки noсheckin в след. строку)— В python файлах запрещаю функции с префиксом
test_, но разрешаю_test_(чтобы тесты не дублировались в test runner-е VSCode)Для кодогенерации (в отдельных случаях я запускаю cog на некоторых файлах. Зачастую — для автовставок картинок в markdown)
Для билда (этот сайт всегда билдится в статику при коммите ➜ я лишь редактирую markdown файлы. На github-pages раскатается актуальная версия)
Для прогона тестов (не люблю все тесты прогонять pre-commit-ом. Иногда через большой рефакторинг прохожу и приходится
--no-verifyиспользовать частенько. Сейчас ограничиваюсь прогоном тестов лишь на свои «библиотечные» файлы)
Пример моей конфигурации .pre-commit-config.yaml
Ссылки
- pre-commit (я использую uv, посему, ставлю через
uv add --dev pre-commit; uv run pre-commit --install; uv run pre-commit --install-hooks)
Btw
Иногда хочется закоммитить в репу код, для которого не проходят хуки. Это можно сделать с помощью
git commit --no-verify. У Github Desktop есть опция «Bypass Commit Hooks». В lazygit тоже можно удобно пропускать хукиРазработяги в корпоратах в CI/CD пайплайны могут встраивать стадию lint-а. Но пока изменения запушатся, раннер стартанет, проект подготовится и линтинг завершится, пройдет некоторое время. Куда быстрее локально прогнать линтер перед коммитом и сразу узнать об ошибках (но не говорю, что линтинг в CI/CD — плохо)