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

shi*_*l88 68 git git-merge

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

我的问题是我如何格式化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
Run Code Online (Sandbox Code Playgroud)

las*_*lok 49

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

git commit --amend -m"New commit message"
Run Code Online (Sandbox Code Playgroud)

更改合并提交的提交消息,而不会丢失到合并提交的任何父项的链接.

  • 如果您只想将默认合并提交从"merged branch ... into master"更改,请尝试使用`git merge --no-edit -m"your-custom-commit-message" (4认同)
  • -1:这不回答问题.无论谷歌指向哪里查询,这都不是最佳答案.甚至可能根本不应该回答这个问题. (4认同)
  • @Jasper 从技术上讲是正确的,但作为回答者,标题没有准确地捕捉正文中的问题,这几乎不是我的错。显然人们发现这足以使其升至顶峰,这也几乎不是我的错。现在已经使用了一段时间(并且有足够的声誉这样做,很大程度上是由于这个特定的答案),现在我可能会改为编辑问题,以澄清标题并添加相关问答的链接. (2认同)
  • 在我看来,这是回答者的错误,因为他没有试图回答这个问题,而是回答了一个从未被问过的问题。(如果这个问题没有自我回答,那就不会那么糟糕,但这不会改变任何事情。)也许带有类似但不同问题链接的评论会是一个更好的主意。 (2认同)

R0M*_*RMY 21

看起来像版本Git 1.7.8,你可以做git merge --edit ... 指定提交消息.

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

从此版本开始,交互式会话中的"git merge"命令将启动编辑器,当它自动解析合并以供用户解释生成的提交时,就像"git commit"命令在没有给出时一样提交消息.

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


shi*_*l88 16

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

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

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

1.使用prepare-commit-message作为VonC 建议
此解决方案存在您需要中断提交然后手动提交的问题

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

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

通过在$ 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  
Run Code Online (Sandbox Code Playgroud)

一个人应该定义一个别名提交消息,例如

[alias]  
m = merge --no-ff --no-commit
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

然后执行一个相当严格的命令:

./cmd-name <branch to merge>
Run Code Online (Sandbox Code Playgroud)

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


小智 13

我想做这样的事情.我没有找到任何合理的方式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
Run Code Online (Sandbox Code Playgroud)

用法是:

$ git mergelogmsg branch-name
Run Code Online (Sandbox Code Playgroud)

我将复制别名:

[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" 
Run Code Online (Sandbox Code Playgroud)

如果要复制并粘贴它以进行自定义,请使用上面的内容.以下版本有你不想要的换行符,但我会用来解释我在做什么:

[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"
Run Code Online (Sandbox Code Playgroud)

好的...

第1行将自定义函数作为bash shell脚本启动,因此git知道它不是git命令.它将当前分支(master,如果要将不同的分支合并为master)设置为变量,以便稍后使用它.
第2行使用当前分支和您给出原始命令的分支名称打印第一行(就像在普通合并命令中一样).它将此写入临时文件.
第3行获取传入分支中不在当前分支中的提交日志,并仅将这些提交的主题写入临时文件.
第4行将下一行打印到temp.
第5行获取当前分支中不在传入分支中的提交日志,并仅将这些提交的主题写入临时文件.
第6行在摘要和细节部分之间打印一个小的水平分隔符.
第7行将当前分支和传入分支中的所有提交的日志返回到它们彼此分支之后的时间,或者最后共享一个祖先.左右给出一个箭头,显示提交来自哪个分支.<表示当前分支,>表示进入分支.
第8行执行与传入分支的合并命令,没有快进(所以你得到提交)并且没有提交(所以你必须自己编写一个......但是你没有!)
第9行执行提交带有-e-F参数的命令允许编辑并告诉提交使用指定文件中的文本填充消息.根据需要完成提交消息后,它将提交合并并删除临时文件.

田田!这个;long命令末尾的两个命令使得printf函数不会写入控制台,只会写入文件.


prz*_*adu 9

一旦你合并你<branch A><branch B>,git将自动提交一条消息说"合并分支<branch A><branch B>.

如果你想自定义git的合并提交消息,你可以尝试:

$ git commit --amend -m "Your merge message"
Run Code Online (Sandbox Code Playgroud)

此命令将git的合并提交消息更新为您的提交消息.

你也可以尝试:

$ git merge <branch A> --no-commit
Run Code Online (Sandbox Code Playgroud)

它会将您的<branch B>with <branch A><Branch B>'s提交和提交消息列表 合并

如果它不能快进,那么你会得到这样的东西:

Automatic merge went well; stopped before committing as requested

# check this with git status 
$ git status
Run Code Online (Sandbox Code Playgroud)

它会告诉你,你的提交已经添加到阶段但尚未提交,所以,你可以在不运行的情况下提交它们git add:

$ git commit -m "your merge commit message"
Run Code Online (Sandbox Code Playgroud)

如果您想要更改<branch B>上次提交消息,那么您可以尝试:

$ git commit --amend -m "your new commit message"
Run Code Online (Sandbox Code Playgroud)

但是,通常,我们不会更新其他提交消息,除非它们不正确.

假设,你在git merge之后遇到冲突,然后简单地解决你的冲突并做:

$ git add .
$ git commit -m "your commit message"
Run Code Online (Sandbox Code Playgroud)


Cas*_*bel 6

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


Von*_*onC 5

您可以尝试定义一个prepare-commit-msg钩子示例确实会生成一些自定义的“默认提交消息”)