Git предоставляет мощный инструмент для автоматизации под капотом: перехватчики. В этой статье вы узнаете о фреймворке предварительной фиксации, который может внести порядок и структуру в вашу коллекцию скриптов.
Работа с Git не совсем тривиальна. Даже такие простые вещи, как отмена шага, выходят далеко за рамки простого ярлыка отмены, но как только в репозитории работает целая команда, источники проблем вырастают до небес.
Сам Git очень хорошо справляется с простыми “сложными” проблемами, такими как конфликты слияния или отсутствующие обновления, и помогает с удивительно четкими сообщениями об ошибках. Однако, когда дело доходит до более сложных или “мягких” проблем, Git также бессилен.
Пример: Предположим, что команда согласовала конкретную политику фиксации, например, писать сообщения о фиксации понятным, значимым образом и с заданным форматированием. Тогда, к лучшему это или к худшему, вам в первую очередь придется положиться на надежность всех членов команды.
Именно здесь Git-перехватчики могут вступить в действие и принудительно отправлять правильные сообщения о фиксации — или, скорее, поощрять их, как мы покажем позже на конкретном примере.
Git-перехватчики — это, по сути, нечто очень простое: скрипты, которые автоматически выполняются при определенных событиях рабочего процесса. Скрипты могут быть написаны на любом скриптовом языке, таком как Python для обширных манипуляций или в виде Bash-скрипта для небольших вмешательств. События рабочего процесса относятся к отдельным шагам, таким как фиксация и отправка на стороне клиента или обновления на стороне сервера.
Использование так же просто, как и концепция: все скрипты находятся в каталоге “./git/hooks” под фиксированными описательными именами, такими как “pre-push». Для удобства многие скрипты по умолчанию содержат файлы примеров в папке hooks.
Для простого теста достаточно просто написать команду типа “echo foobar” в сценарии предварительной фиксации; терминал уже отображает сообщение “foobar» до фактического выполнения инструкции push.
Для отдельных перехватчиков важны три аспекта: когда именно они выполняются, т.e. Запускаются какой командой git? Какие параметры передаются? И выполняется ли скрипт на стороне клиента или в удаленном репозитории? Ниже я показываю наиболее важные перехватчики в обычном рабочем процессе Git. Всего около 28 перехватчиков, здесь обсуждаются только 15, которые используются более регулярно.
Давайте начнем довольно необычно с перехватов, которые запускаются “git am”, то есть при обработке исправлений по электронной почте. Здесь есть три перехвата.:
Команда “git commit” вызывает в общей сложности четыре перехватчика:
Принцип работы предварительной фиксации довольно прост: фреймворк устанавливается в репозиторий Git и запускается с помощью команды “git commit”. Затем он выполняет установленные перехватчики в соответствующее время, точнее, на определенном этапе (фиксация, нажатие и т.д.).
Сами перехватчики могут быть написаны практически на любом языке или для разных сред, включая Conda, Docker, Dotnet, Node, Lua, Perl, Ruby, Rust, Pygrep и, конечно, Python и shell-код. Предварительная фиксация обычно также обрабатывает любые зависимости, которые требуются среде для запуска сценариев. В некоторых случаях, например, с помощью shell script, пользователи должны и могут позаботиться об этом сами.
Вы получаете еще большую гибкость за счет хранения перехватчиков: хотя они могут храниться локально и непосредственно в соответствующем репозитории, по умолчанию они извлекаются из собственного репозитория — как это обычно бывает с менеджерами пакетов.
Сама функция предварительной фиксации указывает Pip, Brew и Conda для установки — однако пакеты Snap и Apt также показаны в Ubuntu, которые не обновлены. Мы рекомендуюем устанавливать через Pip:
pip install pre-commit
Важно обращать внимание на любые сообщения об ошибках; в нашем случае установка была установлена в каталог “~/.local/”, которого нет в path. Версия Apt, в свою очередь, была установлена в path как обычно. Если все работает, в “pre-commit —version” должен быть указан номер версии.
Теперь перейдите к нужному репозиторию. Вся настройка выполняется в файле “pre-commit-config.yaml”, который вы можете поместить в корневой каталог вашего репозитория. Для начала вы можете создать простой пример конфигурации, использующей несколько перехватчиков из репозитория перехватчиков предварительной фиксации:
pre-commit sample-config > .pre-commit-config.yaml
Пример конфигурации просто выводится по умолчанию; вы должны заполнить им конфигурацию YAML самостоятельно, как указано выше. Содержание приятно простое, вот выдержка из демонстрационной конфигурации:
repos: - repo: https://github.com/Pre-Commit/Pre-Commit-hooks rev: v3.2.0 hooks: - id: trailing-whitespace
Итак, необходимы три элемента информации: репозиторий с перехватами, тег для желаемого выпуска и идентификаторы желаемых перехватов — подробнее об этом позже. Загруженный здесь перехватчик, что неудивительно, удалит ненужные пробелы в концах строк.
Теперь конфигурация готова, и вы можете установить pre-commit:
pre-commit install
С помощью этой команды файл “pre-commit” просто сохраняется в каталоге ”.git /hooks» — таким образом, перехватчик предварительной фиксации активируется и выполняет предварительную фиксацию с созданной конфигурацией во время “git commit». И да, немного сбивает с толку тот факт, что фреймворк, Git-хук и сам файл имеют одно и то же имя “Pre-Commit”.
Вместо новой фиксации перехватчики также могут запускаться вручную, для отдельных файлов или просто для всех файлов, что, конечно, имеет смысл для новых перехватчиков:
pre-commit run --all-files
Это означает, что выполняются все перехватчики , указанные в конфигурации YAML, и при необходимости изменяются файлы — каждый подтверждается красиво отформатированным выводом в форме:
`Trim Trailing Whitespace.................................................Passed - hook id: trailing-whitespace exit code: 1 - files were modified by this hook`
Репозиторий перехватов, по сути, должен содержать только две вещи: сами скрипты перехватов и другую конфигурацию YAML, здесь файл “pre-commit-hooks.yaml”. Лучший способ сделать это — просто разветвить уже используемое репозиторий подключений из проекта предварительной фиксации — напрямую через интерфейс GitHub:
repos: - repo: https://github.com/IHR-REPO/pre-commit-hooks rev: v1.0.0 hooks: - id: trailing-whitespace -
Затем конфигурация в рабочем репозитории требует обновления:
pre-commit autoupdate
Это устанавливает для записи rev в pre-commit.yaml значение последней версии. Если использование предопределенных и разветвленных хуков из вашего собственного репозитория хуков работает, вы можете протестировать свои собственные скрипты.
Этот перехватчик представляет собой очень простой сценарий оболочки, который просто заменяет “foo” на “bar– — в файле “test.sh” в главном каталоге репозитория перехватчиков:
#!/bin/bash sed -i ' s/foo/bar/ ' *
Затем этот хук должен быть известен “pre-commit-hooks.yaml” – для этого вы просто копируете часть хука “завершающий пробел”, показанную выше, и соответствующим образом адаптируете ее:
- id: test name: test description: testing stuff entry: ./test.sh language: script types: [text] stages: [commit, push, manual]
В дополнение к имени и идентификатору, здесь необходимо изменить две записи: “script» указывается как “язык”, а для “entry” должен быть указан путь к скрипту относительно основного каталога репозитория подключений; Здесь, например, test.sh сам находится в главном каталоге.
Другие записи для ”типов» и “этапов” необязательны; на этом этапе вы можете указать, что перехватчик учитывает только текстовые файлы и какими этапами это должно быть ограничено.
И снова теперь необходимо создать новый релиз в репозитории hooks. Теперь не хватает последнего шага: новый пользовательский перехватчик должен быть добавлен в pre-commit-config.yaml в рабочем репозитории:
repos: - repo: https://github.com/IHR-REPO/pre-commit-hooks rev: v1.0.1 hooks: - id: trailing-whitespace - id: test
После окончательного обновления появляется доступ к тестовому перехвату.
pre-commit autoupdate
Очень важно, хотя и не зависит от предварительной фиксации: скрипт должен быть исполняемым — и, конечно, об этом также необходимо сообщить в git. Это работает при добавлении скрипта с помощью “git add”, но также и после:
git update-index --chmod=+x test.sh
Два репозитория, две конфигурации YAML, релизы в одном, обновления в другом репозитории, документация, которая на самом деле использует Python только в качестве примера — предварительная фиксация не совсем интуитивно понятна, и первый час может быть довольно неприятным, но после этого это отличный инструмент.