每次我进行合并时,我都需要生成一个合并提交,并且我希望它不仅仅是所有提交的摘要。
我的问题是如何格式化 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
我知道这不是在回答最初的问题,但是为了像我这样的 git noobs 到达这个页面,因为它目前是“git change merge commit message”的第一个谷歌结果,我会提到它是可能的至:
git commit --amend -m"New commit message"
更改合并提交的提交消息,而不会丢失与合并提交的任何父项的链接。
我发现有两种方法可以解决这个问题
注意:不要同时使用两者,因为如果提交失败合并它会再次将日志添加到底部。
个人注意:我使用的是第一个解决方案,因为它完全依赖于 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 那么它将在底部生成)
我想做这样的事情。我没有找到任何合理的方法让 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 shell 脚本启动,因此 git 知道它不是 git 命令。它将当前分支(如果您将不同的分支合并到主分支,则为主分支)设置为一个变量,以便我们稍后使用它。
第 2 行 使用当前分支和分支打印第一行您给原始命令的名称(就像在普通的合并命令中一样)。它将其写入临时文件。
第 3 行 获取传入分支中不在当前分支中的提交的日志,并仅将这些提交的主题写入临时文件
Line 4 将下一行打印到 temp。
Line 5 获取当前分支中不在传入分支中的提交日志, 并仅将这些提交的主题写入临时文件。
第 6 行 在摘要和详细信息部分之间打印一个小的水平分隔符。
第 7 行 将当前分支和传入分支中所有提交的日志返回到它们刚从彼此分支或最后共享祖先之后的时间。左右给出一个箭头,显示提交来自哪个分支。 <表示当前分支和>表示传入分支。
第 8 行 执行与传入分支的合并命令,没有快进(所以你得到一个提交)和没有提交(所以你必须自己写一个.. . 啊,但你没有!)
第 9 行 使用 -e
和 -F
参数执行提交命令,以允许编辑并告诉提交使用指定文件中的文本。根据需要完成提交消息后,它会提交合并并删除临时文件。
多田!该长命令末尾的两个 ;
使 printf 函数不会写入控制台,而只会写入文件。
将 <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"
--amend
?不应该只是git commit -m "your commit message"
吗?
--no-commit
标志时,“因为没有为合并完成任何提交”,就像您所做的那样:-)
git add .
,但是,您可以直接使用 git commit -m "your commit message"
提交合并
现在还有一个用于 git-merge
的 --log
选项,它可以完成您想要的一半 - 它将短日志(提交摘要)放在合并消息中。不过,完整的解决方案必须使用 VonC 的答案中的钩子。
commit_tree
。
您可以尝试定义 prepare-commit-msg hook(sample one 确实会生成一些自定义“默认提交消息”)
git merge
期间是否激活了 commit-msg
钩子?
迟到了,但现在我们可以使用
git merge --squash <branch>
将另一个分支合并到我当前分支上的单个提交中并使用所有合并的提交预填充我们的提交消息消息——以及详细的消息,不仅仅是单行。
我为这个命令寻找了很多年。
除了 Christian Severin 的 answer 中提到的 git merge --squash
之外,您现在还可以使用配置 merge.suppressDest
作为自定义(一小部分)提交消息的新方法。
在 Git 2.29(2020 年第四季度)中,“git merge
”(man) 学会了在具有 merge.suppressDest
配置的默认合并消息的标题末尾选择性地省略“into <branch>
”。
请参阅 Junio C Hamano (gitster
) 的 commit 6e6029a(2020 年 7 月 29 日)和 commit 2153192(2020 年 7 月 30 日)。
(由 Junio C Hamano -- gitster
-- 在 commit 341a196 中合并,2020 年 8 月 1 日)
fmt-merge-msg:允许再次省略合并目标帮助者:Linus Torvalds 帮助者:Jeff King
在 Git 2.28 中,我们在生成默认合并消息时停止了特殊的大小写“master”,只需删除在消息末尾压制“进入 'master'”的代码。引入多值 merge.suppressDest 配置变量,该变量提供一组 glob 以匹配进行合并的分支的名称,让用户指定应该缩短哪个分支 fmt-merge-msg 的输出。未设置时,默认情况下将“master”用作变量的唯一值。上述举措主要是在没有相关配置的存储库中恢复 2.28 之前的默认设置。
git config
现在在其 man page 中包含:
merge.suppressDest 通过向这个多值配置变量添加一个与集成分支名称匹配的 glob,为合并到这些集成分支中计算的默认合并消息将在其标题中省略“into
和:
还原“fmt-merge-msg:停止特别对待主人”
这将恢复提交 489947cee5095b168cbac111ff7bd1eadbbd90dd,它在准备默认合并消息时停止将合并到“主”分支中视为特殊。由于目标不是将任何单个分支指定为特殊分支,因此它通过在任何和所有分支的默认合并消息标题的末尾保留“into
一个非常简单的 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 log --graph
停止绘制分支图。git merge --no-edit -m "your-custom-commit-message"