Подготовить сообщение Git commit с именем частичной ветки

Мое соглашение об именовании ветвей как таковое:

ticket-45-my-new-feature-branch-description

В настоящее время я использую этот код в своем файле .git/hooks/prepare-commit-msg для добавления каждого сообщения фиксации с именем ветки как таковым:

BRANCH_NAME=$(git branch 2>/dev/null | grep -e ^* | tr -d ' *')
if [ -n "$BRANCH_NAME" ] && [ "$BRANCH_NAME" != "master" ]; then
    echo "[$BRANCH_NAME] $(cat $1)" > $1
fi

Конечный результат:

[ticket-45-my-new-feature-branch-description] test commit

То, что я пытаюсь выполнить, выводится следующим образом:

[ticket-45] test commit

Брауни указывает, можем ли мы его использовать:

[ticket-45] test commit

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

ticket-123-branch-name
abc-22-my-branch
ua-11-my-feature

Единственное, что является общим, это тот факт, что мне нужно все до второго "-".

Любая помощь очень ценится!!!

Ответ 1

Итак, сначала:

BRANCH_NAME=$(git branch 2>/dev/null | grep -e ^* | tr -d ' *')

является основным излишеством:-) Использование:

branch=$(git symbolic-ref --short HEAD) || ...

чтобы получить имя текущей ветки. Часть после || - "что делать, если вы не на ветке" (т.е. Если вы находитесь в режиме "отсоединенной головы" ), вам придется решить это для себя. (Ваш текущий код устанавливает BRANCH_NAME в пустую строку, для этого вам даже не нужна часть ||, но вы можете добавить -q или 2>/dev/null, чтобы избежать "фатального": сообщение от символа-ref.)

Остальное - это просто базовые сценарии. В bash вы можете напрямую использовать регулярное выражение, в старых sh вы можете вызывать expr или sed. Оба sed и tr могут иметь верхний регистр-ify, но sed также может выполнять регулярное выражение, поэтому он выглядит как хороший кандидат:

$ trimmed=$(echo $branch | sed -e 's:^\([^-]*-[^-]*\)-.*:\1:' -e \
    'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/')
$ echo $trimmed
TICKET-45

Наконец, это немного опасно:

echo "some stuff $(cat $1)" > $1

поскольку вы в зависимости от оболочки расширяете $(cat $1) до того, как он обрезает выходной файл для части > $1. (Очевидно, что это работает, но вы подвержены капризам оболочки.) Лучше использовать временный файл или, возможно, еще один sed, но на месте:

sed -i .bak -e "1s:^:[$trimmed] :" $1
# or use -i '', but note minor warning in sed man pages

Вышеуказанное тестирование проводится только по частям, но должно работать.