如何自定义git的合并提交消息?

时间:2010-06-30 11:42:30

标签: git git-merge

每次进行合并时,我都需要生成合并提交,我希望它不仅仅包含所有提交的摘要。

我的问题是如何格式化git-fmt-merge-msg或决定此自动消息的内容(我可以在提交后通过修改它并使用git-log --pretty手动完成此操作=格式: '...')

例如,我想将其格式化为:

 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

10 个答案:

答案 0 :(得分:51)

我知道这不是回答原来的问题,但是为了像我这样的git noobs到达此页面的好处,因为它是目前Google git change merge message的第一个结果,我会提到有可能:

git commit --amend -m"New commit message"

更改合并提交的提交消息,而不会丢失指向合并提交的任何父级的链接。

答案 1 :(得分:18)

从版本Git 1.7.8看起来可以git merge --edit ... 指定提交消息。

1.7.10开始,进入编辑模式将是默认行为

  

从这个版本开始,交互式会话中的“git merge”命令将启动一个编辑器,它会自动解析合并,以便用户解释生成的提交,就像“git commit”命令执行时一样。给出提交消息。

(虽然我在Windows上的msysgit中没有看到它)

答案 2 :(得分:15)

我发现有两种方法可以解决这个问题

note :不要同时使用两者,就好像提交无法合并一样,它会再次将日志添加到底部。

个人笔记:我正在使用第一个解决方案,因为它完全依赖于git的钩子和配置属性,而不是外部脚本。
对于一个真正的解决方案,人们必须扩展名为'fmt-merge-msg'的git命令,该命令在传递--log选项时生成oneline描述(如果你真的需要这个解决方案,你必须创建自己的补丁(for git)并从源代码编译它。

<强> 1。使用prepare-commit-message作为VonC suggested
 这个解决方案有一个问题,你需要中断提交,然后手动提交

设置将构建所需提交消息的别名:

[alias]  
lm = log --pretty=format:'%s%n   by %C(yellow)%an%Creset (%ad)%n %n%b' --date=local

通过在$ GIT_DIR / hooks /中创建可执行的prepare-commit-msg来创建prepare-commit-msg挂钩

#!/bin/sh
#...

case "$2,$3" in  
  merge,)  
  echo "Merge details:" >> $1  
  echo "" >> $1  
  git lm ORIG_HEAD..MERGE_HEAD >> "$1" ;;  
*) ;;  
esac  

应该定义一个别名commit msg,例如

[alias]  
m = merge --no-ff --no-commit

<强> 2。使用自动生成合并的自定义命令
(使用1中创建的lm别名。)

#!/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>

如果您仍希望获得提交的oneline描述,则需要向-m参数添加新命令或其他内容(如果使用--log,则会在底部生成)

答案 3 :(得分:10)

我想做这样的事情。我找不到让git fmt-merge-msg工作的任何合理方法。我认为这不符合我希望的方式(传递用于消息的完全自定义文本)。因此,我想出了另一种使用-no-commitcommit -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 shell脚本启动自定义函数,因此git知道这不是git命令。它将当前分支(如果将其他分支合并到master中,则为master)设置为变量,以便我们稍后使用。
第2行使用当前分支和您赋予原始命令的分支名称(与在普通合并命令中一样)打印第一行。它将其写入临时文件。
第3行获取传入分支中不在当前分支中的提交的日志,并仅将这些提交的主题写到临时文件中。
第4行将下一行打印到温度。
第5行获取当前分支中不在传入分支中的提交的日志,并将仅这些提交的主题写到临时文件中。
第6行在摘要和详细信息部分之间打印一些水平分隔符。
第7行将当前分支和传入分支中的所有提交的日志追溯到它们彼此分支或最后共享祖先之后的时间。左右方向提供一个箭头,显示提交来自哪个分支。 <表示当前分支,而>表示传入分支。
第8行对传入的分支执行合并命令,该分支没有快进(因此您可以提交),也没有提交(因此您必须自己编写一个……),但是您不必!)
第9行使用-e-F参数执行commit命令,以进行编辑并告诉提交使用指定文件中的文本填充消息。根据需要完成提交消息后,它将提交合并并删除临时文件。

多田!该长命令末尾的两个;使它生效,因此printf函数不会写到控制台,而只会写到文件。

答案 4 :(得分:8)

<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"

答案 5 :(得分:6)

现在--log还有一个git-merge选项,它可以满足你想要的一半 - 它将短日志(提交摘要)放在合并消息中。但是,完整的解决方案必须使用像VonC的答案中的钩子。

答案 6 :(得分:3)

您可以尝试定义prepare-commit-msg hooksample one会生成一些自定义的“默认提交消息”)

答案 7 :(得分:1)

迟到了,但现在我们可以使用
getFragmentManager().beginTransaction().replace(R.id.flContenedor, inf).addToBackStack(null).commit();
将另一个分支合并到我当前分支上的单个提交并使用所有合并的提交消息预先填充我们的提交消息 - 以及详细消息,而不仅仅是单行。 我找了这个命令的年龄。

答案 8 :(得分:0)

一个非常简单的bash函数,它设置了一个默认消息并添加了你的参数。 如果您想进行更改,它会使用--edit开关打开您的编辑器。

编辑〜/ .bashrc或bash_aliases。 (别忘了source ~/.bashrc)在bashrc中应用更改

function mergedevelop()
{
    git merge --no-ff --edit -m "master <-- develop: $1" develop;
}

使用:

mergedevelop "PR #143..."有消息:

master&lt; - develop:PR#143 ...

答案 9 :(得分:0)

除了Christian Severinanswer中提到的git merge --squash之外,您现在还拥有配置merge.suppressDest作为自定义(一小部分)提交的新方法消息。

在Git 2.29(2020年第四季度)中,“ git mergeman学会了在标题的末尾有选择地省略“ into <branch>”具有merge.suppressDest配置的默认合并消息。

请参见commit 6e6029a前的commit 2153192(2020年7月29日)和Junio C Hamano (gitster)(2020年7月30日)。
(由Junio C Hamano -- gitster --commit 341a196中合并,2020年8月1日)

fmt-merge-msg:允许再次忽略合并目标

帮助者:Linus Torvalds
帮助人:杰夫·金

在Git 2.28中,我们在生成默认合并消息时停止了特殊大小写'master',只需删除消息末尾的静噪“ into 'master'”即可。

引入多值merge.suppressDest配置变量,该变量提供一组glob以与要进行合并的分支名称匹配,以让用户指定fmt-merge-msg的输出应针对哪个分支缩短。
如果未设置,默认情况下将'master'用作变量的唯一值。

以上步骤主要是还原没有相关配置的存储库中的2.28之前的默认设置。

git config现在包含在其man page中:

merge.suppressDest

通过添加与积分名称匹配的glob 分支到该多值配置变量, 计算为合并到这些文件中的默认合并消息 集成分支将从以下位置省略“ into <branch name>” 它的标题。

具有空值的元素可用于清除列表 从先前的配置条目中累积的globs。 如果没有定义merge.suppressDest变量,则 默认值master用于向后兼容。

并且:

Revert "fmt-merge-msg:停止特别对待master

这将还原commit 489947cee5095b168cbac111ff7bd1eadbbd90dd,在准备默认合并消息时,该操作停止将合并到'master'分支中作为特殊对象。
由于目标不是将任何一个分支指定为特殊分支,因此通过在所有分支的默认合并消息标题的末尾保留“ into <branchname>”来解决该问题。
一个明显且简单的方法来平等对待每个人,可能是每个分支机构都将其删除,但这会导致信息丢失。

我们将引入一种新的机制,让最终用户指定合并,分支将忽略默认合并消息标题中的“ into <branchname>”,并使该机制在未配置时处理传统'master'再次特别,因此我们之前进行的测试的所有更改都将变得不必要,因为这些测试将在不配置所述新机制的情况下运行。