【问题标题】:how can I customize git's merge commit message?如何自定义 git 的合并提交消息?
【发布时间】:2010-06-30 11:42:30
【问题描述】:

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

我的问题是如何格式化 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

【问题讨论】:

    标签: git git-merge


    【解决方案1】:

    我知道这不是在回答最初的问题,但为了像我这样的 git noobs 访问此页面,因为它目前是“git change merge commit message”的第一个 Google 结果,我会提到可以:

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

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

    【讨论】:

    • 它使git log --graph停止绘制分支图。
    • 如果你只是想将默认的合并提交从“合并的分支...更改为主”,请尝试使用git merge --no-edit -m "your-custom-commit-message"
    • -1:这不能回答问题。无论谷歌在这里提出什么查询,这都不应该是最佳答案。它甚至可能根本不应该是这个问题的答案。
    • @Jasper 技术上是正确的,但作为回答者,标题没有准确地捕捉正文中的问题几乎不是我的错。这也不是我的错,显然人们觉得这很有帮助,足以让它上升到顶峰。现在已经使用了一段时间(并且有足够的声誉,这在很大程度上是由于这个特定的答案),现在我可能会改为编辑问题,以澄清标题并添加指向相关问答的链接.
    • 在我看来,回答者的错是没有尝试回答问题,而是回答了一个从未被问过的问题。 (如果这个问题没有得到自我回答,那就不会那么糟糕了,但这不会改变任何事情。)也许一个带有相似但不同的问题链接的评论会是一个更好的主意。
    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

      注意:不要同时使用两者,如果commit合并失败会再次将日志添加到底部。

      个人说明:我使用的是第一个解决方案,因为它完全依赖于 git 的钩子和配置属性,而不是外部脚本。
      对于真正的解决方案,必须扩展一个名为“fmt-merge-msg”的 git 命令,该命令在传递 --log 选项时生成单行描述(如果你真的需要这个解决方案,你必须创建自己的补丁(对于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  
      

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

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

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

      【讨论】:

      • 好的,太好了。但坦率地说 - 这比它应该的要困难得多。
      • 发布了一个更好的答案!查看已接受的
      【解决方案4】:

      我想做这样的事情。我没有找到任何合理的方法让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 命令。它将当前分支(如果您将不同的分支合并到主分支,则为主分支)设置为一个变量,以便我们稍后使用它。
      第 2 行使用当前分支和分支打印第一行您给原始命令的名称(就像在普通的合并命令中一样)。它将这个写入一个临时文件。
      第 3 行 获取传入分支中不在当前分支中的提交的日志,并仅将这些提交的主题写出到临时文件中
      Line 4 将下一行打印到 temp。
      Line 5 获取当前分支中不在传入分支中的提交日志, 并仅将这些提交的主题写入临时文件。
      第 6 行 在摘要和详细信息部分之间打印一个小的水平分隔符。
      第 7 行 将当前分支和传入分支中所有提交的日志返回到它们刚从彼此分支或最后共享祖先之后的时间。左右给出一个箭头,显示提交来自哪个分支。 表示传入分支。
      第 8 行 执行与传入分支的合并命令,没有快进(所以你得到一个提交)和没有提交(所以你有自己写一个...啊,但你没有!)
      第 9 行 使用 -e-F 参数执行提交命令,以允许编辑并告诉提交用指定文件中的文本填充消息。根据需要完成提交消息后,它会提交合并并删除临时文件。

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

      【讨论】:

      • 这太棒了!!它与问题完美契合,并且可以轻松定制。谢谢!
      • 确实,我已经对其进行了更多定制。我只是为一个特定项目制作的,但我可能会将它用于所有合并。
      【解决方案5】:

      一旦你将&lt;branch A&gt; 合并到&lt;branch B&gt;,git 会自动提交一条消息,说“将分支&lt;branch A&gt; 合并到&lt;branch B&gt;

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

      $ git commit --amend -m "Your merge message"
      

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

      你也可以试试:

      $ git merge <branch A> --no-commit
      

      它将您的&lt;branch B&gt;&lt;branch A&gt; 合并,与&lt;Branch B&gt;'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"
      

      如果你想更改&lt;branch B&gt; 的最后一条提交消息,那么你可以再次尝试:

      $ git commit --amend -m "your new commit message"
      

      但是,一般来说,我们不会更新其他提交消息,除非它们不正确。

      假设,你在 git merge 之后发生冲突,然后简单地解决你的冲突并执行:

      $ git add .
      $ git commit -m "your commit message"
      

      【讨论】:

      • 您为什么要在答案的最后一行对尚未发生的提交执行--amend?不应该只是git commit -m "your commit message"吗?
      • 我的错,感谢您指出。它应该是 git commit -m "your commit message" 因为没有为合并完成提交。
      • “因为没有为合并完成任何提交”当您指定 --no-commit 标志时,就像您所做的那样:-)
      • 这里, git merge b --no-commit 将分支 b 合并到分支 a,所有分支 b 提交(这是显而易见的)和分支 b 的提交消息。它不会添加额外的提交消息,例如:“merged branch b with branch a”
      • 如果您的合并不是快进的,您将收到类似“自动合并顺利;在按要求提交之前停止”的消息。现在,您不需要运行git add .,但是,您可以直接使用git commit -m "your commit message" 提交合并
      【解决方案6】:

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

      【讨论】:

      • 好吧,我已经在全局范围内设置了该选项,挂钩不会起作用,因为它们在合并期间不会激活(除非你用 --no-commit 停止它)
      • "钩子不会起作用,因为它们在合并期间不会激活(除非你用 --no-commit 停止它)";这本身就是一个好问题:为什么在合并的提交部分没有激活任何钩子?
      • @VonC:我认为这是故意的,实际上 - 从源代码的快速浏览中,直接合并调用 commit_tree
      • -m 选项对 --log 很有用。另外,对于像我这样的菜鸟,在检查合并到的分支的结果日志时不要使用 --oneline 选项(使用 --log),否则您只会看到合并提交消息而不是单个提交消息合并后的分支。
      【解决方案7】:

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

      【讨论】:

      • 在某种程度上工作得很好,我必须与 --no-commit 合并,然后才提交,否则 prepare-commit-msg 钩子似乎没有运行(merge_msg 是标准的)。 . 我希望自动添加合并的完整详细信息,因为这些是我提交给 CVS 的提交
      • @shil88:您是否尝试查看在git merge 期间是否激活了commit-msg 挂钩?
      • @shil88: 刚刚意识到我已经回答了你的第一个问题 (stackoverflow.com/questions/2817897/…): 你终于设法实现了一个钩子来保持 git 和 cvs repo 同步吗?
      • @VonC 抱歉没有足够的声誉来评论答案,但我实现了一个 CVSNT 后命令钩子,经过一小段延迟后强制“主要”Git 存储库执行 cvsimport ......仍在调整它不过,我会在它完全可用时发布我的解决方案(自动提交是一个非常糟糕的主意,现在我更喜欢从我的本地仓库提交)
      • @VonC commit-msg 挂钩未激活
      【解决方案8】:

      聚会迟到了,但现在我们可以使用
      git merge --squash &lt;branch&gt;
      将另一个分支合并到我当前分支上的单个提交中并使用所有合并的提交消息预填充我们的提交消息 - 以及详细消息,而不仅仅是单行。
      我为这个命令寻找了年龄。

      【讨论】:

        【解决方案9】:

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

        在 Git 2.29(2020 年第四季度)中,“git merge(man) 学会了在默认合并消息的标题末尾选择性地省略“into &lt;branch&gt;”与@987654338 @配置。

        参见commit 6e6029a(2020 年 7 月 29 日)和 commit 2153192(2020 年 7 月 30 日)Junio C Hamano (gitster)
        (由 Junio C Hamano -- gitster -- 合并于 commit 341a196,2020 年 8 月 1 日)支持>

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

        帮助:Linus Torvalds
        帮助:Jeff King

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

        引入多值 merge.suppressDest 配置变量,该变量提供一组 glob 以匹配正在进行合并的分支的名称,让用户指定应该缩短哪个分支的 fmt-merge-msg 的输出.
        未设置时,默认使用'master'作为变量的唯一值。

        上述举措主要是在没有相关配置的存储库中恢复 2.28 之前的默认设置。

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

        merge.suppressDest

        通过添加与集成名称匹配的 glob 分支到这个多值配置变量, 为合并到这些中计算的默认合并消息 集成分支将省略“into &lt;branch name&gt;” 它的标题。

        一个值为空的元素可以用来清空列表 从以前的配置条目中累积的 glob。 当没有定义 merge.suppressDest 变量时, 默认值master 用于向后兼容。

        还有:

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

        这将恢复 commit 489947cee5095b168cbac111ff7bd1eadbbd90dd,它在准备默认合并消息时停止将合并到“master”分支视为特殊。
        由于目标不是将任何单个分支指定为特殊分支,因此它通过在任何和所有分支的默认合并消息标题的末尾留下“into &lt;branchname&gt;”来解决这个问题。
        一个明显而简单的平等对待每个人的替代方法可能是为每个分支删除它,但这会导致信息丢失。

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

        【讨论】:

          【解决方案10】:

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

          编辑 ~/.bashrc 或 bash_aliases。 (不要忘记source ~/.bashrc)在你的 bashrc 中应用更改

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

          使用:

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

          master

          【讨论】:

            猜你喜欢
            • 2015-10-30
            • 1970-01-01
            • 2013-01-12
            • 2013-02-07
            • 2011-11-08
            • 2019-11-22
            • 2023-04-11
            • 2011-11-06
            • 1970-01-01
            相关资源
            最近更新 更多