Вопрос или проблема
Я работаю над хуккой git под названием “commit-msg”, которая проверяет наличие определенной информации в сообщении коммита (идентификатор JIRA тикета). Однако я понимаю, что если коммит является коммитом слияния, мы не можем ожидать наличия JIRA тикета, так как он иногда создается автоматически без вмешательства человека.
Я знаю, что завершенные коммиты слияния имеют двух (или более) родителей, поэтому именно так можно обнаружить коммиты слияния, которые уже зафиксированы, но в случае с git хукком коммит слияния еще не существует.
Я не думаю, что проверка на наличие слова “merge” в комментарии коммита является достаточной.
Я увидел этот пост: Figure out merged commit in prepare-commit-msg hook
Очень уважаемый ответ был написан почти десять лет назад. Надеюсь, он все еще актуален. Меня также интересуют некоторые детали в этом ответе. Ответчик описывает эту переменную окружения “GITHEAD_”. Каким именно будет значение этой переменной? Будет ли это идентификатор коммита? Если да, то к какому коммиту это соответствует?
Ответ или решение
Введение работы с Git-хуками требует определенного уровня технической подготовки и понимания внутренней механики Git. Одним из популярных хуков является commit-msg
, который срабатывает сразу после ввода пользователем комментария к коммиту и позволяет проверить правильность формата этого сообщения. Вы сталкиваетесь с задачей, проверить наличие идентификатора JIRA в комментариях обычных коммитов, но при этом обеспечить гибкость проверки для ситуаций, когда идет работа с merge-коммитами, которые нередко создаются автоматически, и их формат может отличаться.
Теория
Git предоставляет многочисленные хуки для различных стадий работы с коммитами, ветками, пушами и многим другим. commit-msg
— это хук, который запускается со сдаваемым в него в качестве аргумента файлом с сообщением коммита. Ваша задача — модифицировать commit-msg
так, чтобы он принимал только те коммиты, которые содержат JIRA-токен в комментарии, но игнорировал наличие этого токена в merge-коммитах.
Интересная особенность merge-коммитов заключается в том, что они имеют два или более родительских коммита, что можно определить командой git rev-parse --verify HEAD^2
. Однако, в контексте работы хука commit-msg
, который срабатывает до того, как новый коммит будет завершен, такой подход неприменим. Следовательно, необходимо будет искать иной метод определения merge-коммита в рамках именно commit-msg
.
При создании merge-коммита Git может автоматически генерировать сообщение, которое может содержать стандартную строку "Merge branch…", но полагаться исключительно на эту строку ненадежно, так как сообщение может быть изменено.
Пример
Ранее в обсуждениях появлялось упоминание сред уровня GITHEAD_
, который может быть полезен для выявления контекста — например, определения того, что коммит создается в процессе слияния. Однако конкретика реализации в этом случае может зависеть от настроек среды и версии системных инструментов.
Дополнительно многие разработчики рекомендуют использовать prepare-commit-msg
хук для предзаполнения сообщений merge-коммитов необходимыми строками, позволяя упростить последующее оперирование с сообщением в commit-msg
. Можно рассмотреть подобные рекомендации:
-
Создание хука
prepare-commit-msg
: данный хук запускается даже в случае merge-процессов и может манипулировать начальной версией сообщения, добавляя туда специальные идентификаторы, по которымcommit-msg
может определять тип коммита. -
Определение условий для слияния: можно ориентироваться на ограничение по объему входящих изменений или количество родительских веток, которые участвуют в операции.
Применение
Исходя из вышесказанного, вы могли бы авторизировать ваш commit-msg
хук следующим образом:
-
Настройка
prepare-commit-msg
хука: создайте в директории.git/hooks
файлprepare-commit-msg
и наполните его следующим содержимым:#!/bin/sh COMMIT_MSG_FILE=$1 COMMIT_SOURCE=$2 SHA1=$3 if [ "$COMMIT_SOURCE" = "merge" ]; then echo "[MERGE]" >> "$COMMIT_MSG_FILE" fi
Данный скрипт добавляет строку
[MERGE]
в сообщения всех merge-коммитов. Эта строка будет указателем дляcommit-msg
хука. -
Создание и настройка
commit-msg
хука: поставьте в.git/hooks
файлcommit-msg
:#!/bin/sh COMMIT_MSG_FILE=$1 # Забираем первое слово из сообщения FIRST_WORD=$(head -n 1 "$COMMIT_MSG_FILE" | awk '{print $1}') if [ "$FIRST_WORD" != "[MERGE]" ] && ! grep -q "JIRA-\d\+" "$COMMIT_MSG_FILE"; then echo "Вы должны указать JIRA ID в сообщении коммита!" exit 1 fi
Этот примерный контекст продемонстрирует, как вы можете управлять сложным процессом проверки сообщений посредством использования разных хуков, работая в рамках современных требований к разработке программного обеспечения. Важно помнить, что затронутая концепция может быть расширена в зависимости от ваших специфических требований и ожидаемых параметров верификации.