Как я могу настроить сообщение коммит слияния в 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 на момент написания этого ответа.

Другие вопросы по тегам