Как я могу настроить сообщение коммит слияния в Git?
Каждый раз, когда я делаю слияние, мне нужно создать коммит слияния, и я бы хотел, чтобы в нем было больше, чем просто сводка всех коммитов.
У меня вопрос, как мне отформатировать git-fmt-merge-msg или что определяет это автоматическое сообщение (я могу сделать это вручную после коммита, изменив его и используя git-log --pretty=format:'...')
Например, я хотел бы отформатировать его так:
Merge branch 'test'
* test:
[BZ: #123] fifth commit subject
[BZ: #123] fourth commit subject
[BZ: #123] third commit subject
[BZ: #123] second commit subject
[BZ: #123] first commit subject
__________________________________________
Merge details:
[BZ: #123] fifth commit subject
at 2010-06-30 11:29:00 +0100
- fifth commit body
[BZ: #123] fourth commit subject
at 2010-06-30 11:22:17 +0100
- fourth commit body
[BZ: #123] third commit subject
at 2010-06-30 11:21:43 +0100
- third commit body
[BZ: #123] second commit subject
at 2010-06-30 11:21:30 +0100
- second commit body
[BZ: #123] first commit subject
at 2010-06-30 11:29:57 +0100
- first commit body
11 ответов
Я хотел сделать что-то подобное. Я не нашел разумного способа получить git fmt-merge-msg
работать. Я думаю, что это не работает так, как я надеялся (передавая полностью собственный текст для использования в сообщении). Поэтому вместо этого я нашел другой способ, используя -no-commit
а также commit -F
команды. Вывод, конечно, настраиваемый, но он отражает почти точно то, что вы сказали, что хотели, чтобы вывод был.
Пример вывода сообщения о фиксации:
Merge branch fix4 into master
::SUMMARY::
Branch fix4 commits:
Add fix4b-4
Add fix4b-3
Add fix4b-2
Add fix4b-1
Branch master commits:
fix4b-5 on master
* * * * * * * * * * * * * * * * * * * * * * * * *
::DETAILS::
commit < 98ffa579e14610b3566e1a3f86556a04dc95a82b
Author: -----
Date: Fri Aug 17 17:23:26 2018 -0400
fix4b-5 on master
commit > 7e386dddee16a7c2588954d25dd6793cdaa1b562
Author: -----
Date: Fri Aug 17 15:18:17 2018 -0400
Add fix4b-4
use log output as commit message
commit 2e630b1998312ec1093d73f9fe77b942407f45e8
Author: -----
Date: Fri Aug 17 15:15:28 2018 -0400
Add fix4b-3
commit > 2e630b1998312ec1093d73f9fe77b942407f45e8
Author: -----
Date: Fri Aug 17 15:15:28 2018 -0400
Add fix4b-3
commit > c9bb199be49c17ca739d019d749263314f05fc46
Author: -----
Date: Fri Aug 17 15:15:27 2018 -0400
Add fix4b-2
commit > 5b622a935c9d078c7d0ef9e195bccf1f98cce5e4
Author: -----
Date: Fri Aug 17 15:15:27 2018 -0400
Add fix4b-1
И использование будет:
$ git mergelogmsg branch-name
Я скопирую псевдоним здесь:
[alias]
mergelogmsg = "!f() { var=$(git symbolic-ref --short HEAD) && printf 'Merge branch %s into %s\n\n::SUMMARY::\nBranch %s commits:\n' $1 $var $1 > temp_merge_msg && git log --format=format:'%s' $var..$1 >> temp_merge_msg && printf '\n\nBranch %s commits:\n' $var >> temp_merge_msg && git log --format=format:'%s' $1..$var >> temp_merge_msg && printf '\n\n* * * * * * * * * * * * * * * * * * * * * * * * *\n::DETAILS::\n' >> temp_merge_msg && git log --left-right $var...$1 >> temp_merge_msg && git merge --no-ff --no-commit $1 && git commit -eF temp_merge_msg; rm -f temp_merge_msg;}; f"
Если вы хотите скопировать и вставить его, чтобы настроить его, используйте выше. В приведенной ниже версии есть разрывы строк, которые вы не хотите, но я буду использовать, чтобы объяснить, что я делаю:
[alias]
1 mergelogmsg = "!f() { var=$(git symbolic-ref --short HEAD) &&
2 printf 'Merge branch %s into %s\n\n::SUMMARY::\nBranch %s commits:\n' $1 $var $1 > temp_merge_msg &&
3 git log --format=format:'%s' $var..$1 >> temp_merge_msg &&
4 printf '\n\nBranch %s commits:\n' $var >> temp_merge_msg &&
5 git log --format=format:'%s' $1..$var >> temp_merge_msg &&
6 printf '\n\n* * * * * * * * * * * * * * * * * * * * * * * * *\n::DETAILS::\n' >> temp_merge_msg &&
7 git log --left-right $var...$1 >> temp_merge_msg &&
8 git merge --no-ff --no-commit $1 &&
9 git commit -eF temp_merge_msg; rm -f temp_merge_msg;}; f"
Хорошо...
Строка 1 запускает пользовательскую функцию как скрипт оболочки bash, поэтому git знает, что это не команда git. Он устанавливает текущую ветку (master, если вы объединяете другую ветку в master) в переменную, чтобы мы могли использовать ее позже.
В строке 2 печатается первая строка с использованием текущей ветви и имени ветви, которое вы дали исходной команде (так же, как в обычной команде слияния). Это записывает это во временный файл.
Строка 3 получает журнал коммитов во входящей ветке, которых нет в текущей ветке, и записывает только темы этих коммитов во временный файл.
В строке 4 печатается следующая строка для темп.
Строка 5 получает журнал коммитов в текущей ветке, которых нет во входящей ветке, и записывает только темы этих коммитов во временный файл.
В строке 6 печатается небольшой горизонтальный разделитель между частями сводки и детализации.
Строка 7 получает журнал всех коммитов в текущей ветви и входящей ветви обратно во время, сразу после того, как они ответвляются друг от друга или имеют последнего общего предка. Слева направо показывает стрелку, которая показывает, из какой ветви происходит коммит. <означает текущую ветвь и> означает входящую ветвь.
В строке 8 выполняется команда слияния с входящей ветвью без ускоренной перемотки вперед (поэтому вы получаете фиксацию) и без фиксации (поэтому вы должны написать ее самостоятельно... ах, а вы нет!)
Строка 9 выполняет команду commit с -e
а также -F
параметры, позволяющие редактировать и сообщать коммиту о заполнении сообщения текстом в указанном файле. Как только вы закончите сообщение коммита по желанию, оно завершит слияние и удалит временный файл.
Тада! Два ;
в конце этой длинной команды сделайте так, чтобы функции printf не записывали в консоль, а только в файл.
Я знаю, что это не отвечает на первоначальный вопрос, но в интересах таких же мерзавцев, как я, которые попадают на эту страницу, потому что в настоящее время это первый результат Google для "git change merge commit message", я упомяну, что это возможно чтобы:
git commit --amend -m"New commit message"
изменить сообщение коммита коммита слияния, не теряя ссылку ни на одного из родителей коммита слияния.
Похоже, что с версией Git 1.7.8 вы можете сделать git merge --edit ...
указать сообщение фиксации.
А с 1.7.10 переход в режим редактирования будет поведением по умолчанию
Начиная с этого выпуска, команда "git merge" в интерактивном сеансе запускает редактор, когда он автоматически разрешает слияние для пользователя, чтобы объяснить результирующий коммит, точно так же, как команда "git commit", когда ей не было дано отправить сообщение.
(хотя я не вижу его в msysgit на окнах).
Я обнаружил, что есть два пути решения этой проблемы
примечание: не используйте оба одновременно, так как если фиксация не удастся объединить, она снова добавит журнал внизу.
личное примечание: я использую первое решение, поскольку оно полностью полагается на хуки git и свойства конфигурации, а не на внешний скрипт.
Для реального решения нужно было бы расширить команду git с именем 'fmt-merge-msg', которая генерирует описания oneline при передаче опции --log (если вам действительно нужно это решение, вам придется создать свой собственный патч (для git) и скомпилируйте его из исходного кода).
1. используя prepare-commit-message, как предложил VonC
В этом решении есть проблема, которая заключается в том, что вам нужно прервать коммит, а затем зафиксировать вручную
установка псевдонима, который создаст желаемое сообщение о коммите:
[alias]
lm = log --pretty=format:'%s%n by %C(yellow)%an%Creset (%ad)%n %n%b' --date=local
создание ловушки prepare-commit-msg путем создания исполняемого файла prepare-commit-msg в $GIT_DIR/hooks/ (пример скрипта ниже)
#!/bin/sh
#...
case "$2,$3" in
merge,)
echo "Merge details:" >> $1
echo "" >> $1
git lm ORIG_HEAD..MERGE_HEAD >> "$1" ;;
*) ;;
esac
необходимо определить псевдоним коммитов, такой как
[alias]
m = merge --no-ff --no-commit
2. используя пользовательскую команду, которая автоматически сгенерирует слияние
(используя псевдоним lm, созданный в 1.)
#!/bin/sh
echo ""
echo "merge with commit details -- HEAD..$1"
git merge --no-ff --no-log -m "`git lm HEAD..$1`" --no-commit $1
и затем выполните довольно жесткую команду:
./cmd-name <branch to merge>
если вы все еще хотите иметь on-line описание коммитов, вам нужно добавить новые команды или что-то еще в аргумент -m (если вы используете --log, то он будет сгенерирован снизу)
После того как вы объедините <branch A>
в <branch B>
git автоматически отправит сообщение "ветвь слияния" <branch A>
в <branch B>
,
Если вы хотите настроить сообщение git для фиксации слияния, вы можете попробовать:
$ git commit --amend -m "Your merge message"
Эта команда обновит сообщение о коммите слияния вашего git до вашего сообщения о коммите.
Вы также можете попробовать:
$ git merge <branch A> --no-commit
это объединит ваш <branch B>
с <branch A>
со списком <Branch B>'s
фиксировать и фиксировать сообщения
Если не удается выполнить ускоренную перемотку вперед, вы получите что-то вроде этого:
Automatic merge went well; stopped before committing as requested
# check this with git status
$ git status
Он покажет вам, что ваши коммиты уже добавлены на сцену, но еще не зафиксированы, поэтому вы можете коммитить их без запуска git add
:
$ git commit -m "your merge commit message"
Если вы хотите изменить <branch B>
Последнее сообщение коммита, затем снова вы можете попробовать:
$ git commit --amend -m "your new commit message"
Но, как правило, мы не обновляем другие сообщения о коммитах, если они не являются неправильными.
Предположим, вы получили конфликт после git merge, затем просто разрешите ваш конфликт и выполните:
$ git add .
$ git commit -m "your commit message"
Там также есть --log
вариант для git-merge
Теперь, который делает половину того, что вы хотите - он помещает шортлог (коммиты) в сообщение о слиянии. Полное решение должно будет использовать ловушку, как в ответе VonC, хотя.
Вы можете попытаться определить ловушкуprepare-commit-msg ( пример генерирует некоторые пользовательские "сообщения коммита по умолчанию")
Опаздывает на вечеринку, но в настоящее время мы можем просто использоватьgit merge --squash <branch>
объединить другую ветку в один коммит в моей текущей ветке и предварительно заполнить наше сообщение коммитом всеми слитыми сообщениями коммита - и подробными сообщениями, а не только однострочными.
Я искал целую вечность для этой команды.
В дополнение к git merge --squash
упоминается в Christian Severin"s ответ, теперь у вас есть конфигmerge.suppressDest
как новый способ настроить (небольшую часть) сообщения фиксации.
С Git 2.29 (4 квартал 2020 г.) " git merge
"( человек) научился выборочно опускать"into <branch>
"в конце заголовка сообщения слияния по умолчанию с merge.suppressDest
конфигурация.
См. Commit 6e6029a (29 июля 2020 г.) и commit 2153192 (30 июля 2020 г.) от Junio C Hamano (gitster
).
(Слияние Junio C Hamano -gitster
- в коммите 341a196, 01 августа 2020 г.)
fmt-merge-msg
: разрешить снова пропустить назначение слиянияПомощник: Линус Торвальдс
Помощник: Джефф Кинг
В Git 2.28 мы остановили специальный корпус '
master
'при создании сообщения слияния по умолчанию, просто удалив код для шумоподавления "into 'master'
"в конце сообщения.Ввести многозначные
merge.suppressDest
переменная конфигурации, которая дает набор глобусов для сопоставления с именем ветки, в которую выполняется слияние, чтобы пользователи могли указать, для какой ветки вывод fmt-merge-msg должен быть сокращен.
Когда он не установлен,master
'используется как единственное значение переменной по умолчанию.Вышеупомянутый шаг в основном отменяет значение по умолчанию до 2.28 в репозиториях, у которых нет соответствующей конфигурации.
git config
теперь включает в свою справочную страницу:
merge.suppressDest
При добавлении глобуса, который соответствует именам ветвей интеграции, к этой многозначной переменной конфигурации, сообщение слияния по умолчанию, вычисленное для слияний с этими ветвями интеграции, будет опущено "
into <branch name>
"от его названия.Элемент с пустым значением может использоваться для очистки списка глобусов, накопленных из предыдущих записей конфигурации. Когда нет
merge.suppressDest
переменная определена, значение по умолчаниюmaster
используется для обратной совместимости.
А также:
Revert "fmt-merge-msg
: хватит лечитьmaster
специально"
Это https://github.com/git/git/commit/489947cee5095b168cbac111ff7bd1eadbbd90dd, которая перестала обрабатывать слияния в '
master
'как специальная ветка при подготовке сообщения слияния по умолчанию.
Поскольку цель не состояла в том, чтобы выделить какую-либо отдельную ветвь как особую, она решила ее, оставив "into <branchname>
"в конце заголовка сообщения о слиянии по умолчанию для всех ветвей.
Очевидной и простой альтернативой для одинакового отношения ко всем могло быть удаление сообщения для каждой ветки, но это влечет за собой потерю информации.Мы представим новый механизм, позволяющий конечным пользователям указывать слияния, в которых ветки будут опускать "
into <branchname>
"из заголовка сообщения о слиянии по умолчанию, и заставить механизм, когда он не настроен, обрабатывать традиционные"master
'снова особенным, поэтому все изменения в тестах, которые мы сделали ранее, станут ненужными, поскольку эти тесты будут выполняться без настройки указанного нового механизма.
Очень простая bash-функция, которая устанавливает сообщение по умолчанию и добавляет ваш аргумент. Он открывает ваш редактор с --edit
переключитесь, если хотите внести изменения.
отредактируйте ~/.bashrc или bash_aliases. (Не забудьте source ~/.bashrc
) чтобы применить изменения в вашем bashrc
function mergedevelop()
{
git merge --no-ff --edit -m "master <-- develop: $1" develop;
}
использовать:
mergedevelop "PR #143..."
иметь сообщение:
мастер <- разработка: PR № 143...
Вы можете переопределить или настроить сообщение о слиянии во время слияния с помощью команды ниже:
git merge <branch> -m "<merge message>"
Он был протестирован на git версии 2.34, вы можете найти его в документации, набрав «git merge --help», если у вас установлен git, или на git-merge на момент написания этого ответа.