Как написать git-хук commit-msg для проверки мерж-коммитов иначе, чем обычных коммитов?

Вопрос или проблема

Я работаю над хуккой 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. Можно рассмотреть подобные рекомендации:

  1. Создание хука prepare-commit-msg: данный хук запускается даже в случае merge-процессов и может манипулировать начальной версией сообщения, добавляя туда специальные идентификаторы, по которым commit-msg может определять тип коммита.

  2. Определение условий для слияния: можно ориентироваться на ограничение по объему входящих изменений или количество родительских веток, которые участвуют в операции.

Применение

Исходя из вышесказанного, вы могли бы авторизировать ваш commit-msg хук следующим образом:

  1. Настройка 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 хука.

  2. Создание и настройка 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

Этот примерный контекст продемонстрирует, как вы можете управлять сложным процессом проверки сообщений посредством использования разных хуков, работая в рамках современных требований к разработке программного обеспечения. Важно помнить, что затронутая концепция может быть расширена в зависимости от ваших специфических требований и ожидаемых параметров верификации.

Оцените материал
Добавить комментарий

Капча загружается...