解决合并冲突后如何使用默认的 git commit 消息?

Posted

技术标签:

【中文标题】解决合并冲突后如何使用默认的 git commit 消息?【英文标题】:How to use the default git commit message after resolving merge conflicts? 【发布时间】:2012-12-07 08:43:48 【问题描述】:

在进行合并和解决冲突之后,是否有一种“简单”的方法可以从命令行接受默认生成的提交消息?我们的一位开发人员将解决所有冲突,然后执行 git commit -m"Merge Commit" 替换列出所有冲突文件的生成提交消息。我想有一个不同的标志,它只需要当前文件而不修改。我知道有一个 -F 或 --file= 选项,但这需要始终知道文件名。

谢谢

【问题讨论】:

【参考方案1】:

只需将编辑器设置为什么都不做的命令:

GIT_EDITOR=true git commit

【讨论】:

我喜欢这个。 :) 虽然我仍然认为这个问题是开发过程中更深层次问题的证据。如果编码人员处于他们“想要”一条无意义的合并消息的情况下,他们可能并没有真正合并两个分支,而只是整合来自上游的新更改。这是一个变基。 哦,我同意您可能希望您的编码人员考虑他们的合并消息——但这不是问题;)。但是你也经常需要做一些简单的合并,因为你不能在你的分支发布时做一个 rebase。 我不太确定这是如何工作的。更改编辑器如何防止 git commit -m"Merge Commit" 语法覆盖默认生成的提交消息?我的问题是我想保留提交消息中列出的所有合并冲突文件。 它没有——在 git(或大多数其他用于这种情况的工具)中没有办法阻止它执行明确告知的操作。如果您不想设置提交消息,请不要使用-m。我的回答只会阻止编辑器弹出。 这对于使用 git 编写“实验”脚本非常有用。例如,gist.github.com/jhoblitt/6bb4305e0b548e8e0de9【参考方案2】:

显然,这里的“正确”答案是让您的开发人员在生成合并提交时为您的团队遵循正确的做法。请注意,您想要的行为曾经是默认行为,并且直到最近 git 才开始要求“人工生成”的合并提交消息。这是有原因的,而且开发人员不会用毫无意义的消息来缩短流程。

也许开发人员在他/她应该改基础时生成合并提交?

也就是说,合并提交是git fmt-merge-msg 的输出,您必须将合并提交的父级提供给它。

【讨论】:

这个命令是怎么用的?文档说它希望标准输入提供合并对象。我尝试通过管道输入它,并通过文件提供父母的修订号,但它一直抛出fatal: Error in line 1:... 与合并相比,变基究竟如何不会引起冲突? @randombits 它仍然需要解决冲突,但不会生成合并提交。【参考方案3】:

默认情况下,当合并失败时,将使用的提交消息保存在 git 文件夹中的一个文件中,通常是.git/MERGE_MSG。冲突解决后,运行 git commit 会将保存的消息提供给默认编辑器。

如果消息不是自己提取的,则可以使用--file 选项将其提供给 git 命令,该选项从文件中读取提交消息:

git commit --file .git/MERGE_MSG

【讨论】:

【参考方案4】:

如果你真的想强制执行这个规则,那么可能有一种方法可以使用 git hooks 强制执行此规则。

每次发生合并冲突时,“组合差异”都会显示哪些文件发生了冲突:git diff HEAD HEAD^1 HEAD^2 --name-only。我不知道从技术上讲,组合差异是否可以显示 更多 个文件,而不仅仅是冲突的文件。

但是,假设它像我们想要的那样工作(这是一个假设),那么你可以有一个 git commit-msg 钩子来检查用户输入的消息并断言

    这是合并提交吗? 如果是这样,组合差异是否显示文件? 如果是这样,字符串“Conflicts:”后跟那些文件名吗?

如果这些条件失败,则让脚本打印以筛选出问题的解释,然后返回非零值以中止提交。你可以让开发者安装这个提交钩子,或者你也可以将它安装在服务器上以确保它强制执行。

【讨论】:

【参考方案5】:

根据the docs,我刚刚尝试了这个简单的命令,它对我有用:

git commit --no-edit

然后,运行git log 以确认已使用默认消息。

【讨论】:

或者更短的输出:git log -1. 这似乎也适用于merge 命令,如git merge master --no-edit【参考方案6】:

git commit --file .git/MERGE_MSG 如前所述很好,但忽略了几点:

当前目录不是最顶层目录 当前存储库是一个 Git 子模块,因此没有 .git 目录,而是一个文件 .git

并且可选:

MERGE_MSG 包含一些关于有冲突的文件的信息。

前两点可以和git rev-parse一起使用:

git commit -F "$(git rev-parse --git-dir)/MERGE_MSG"

或者,或者,使用 Git 别名:

commit-merge = !cat $(git rev-parse --git-dir)/MERGE_MSG | git commit -F -

这适用于“普通”存储库和子模块。如果应该丢弃 # 标记的冲突标记,为简单起见,可以只取合并消息的第一行:

git commit -m $(head -1 $(git rev-parse --git-dir)/MERGE_MSG)

或其他别名:

commit-merge = !head -1 $(git rev-parse --git-dir)/MERGE_MSG | git commit -F -

我不得不在别名中使用 -F 键,因为我无法让 Git 发出要在使用 bash 生成的命令中处理的引号(否则 git commit 会在合并期间抱怨部分提交)。


两天前为 released 的 Git 2.12.0 引入了 git merge --continue 以进行合并提交,该提交在合并期间因冲突而停止。它也适用于子模块,但至少目前不接受 --no-edit,因此建议编辑器在结束合并之前更改提交消息。

【讨论】:

【参考方案7】:

您可以使用默认的 "git commit" 而不显示任何消息。这将触发控制台中的 VIM 编辑器。 VIM 中会出现默认消息,只需使用命令 ":wq" 应用合并并退出 VIM。

以下步骤的演练:

git commit (hit enter)

:wq (to exit and apply merge in VIM editor)

【讨论】:

【参考方案8】:
$git commit --amend --no-edit
它将接收您之前提交的消息,并且不会有任何改变。 当您解决任何 merge conflict 并希望获取之前提交的消息并在您的 feature branch 中应用主代码以避免冲突时,这将很有帮助。

【讨论】:

以上是关于解决合并冲突后如何使用默认的 git commit 消息?的主要内容,如果未能解决你的问题,请参考以下文章

Git分支(5/5) -- 解决合并的冲突

idea中git的add,commit,创建分支,合并分支,解决冲突...

git合并其中一个提交

git中merge和rebase的区别

git merge和rebase的区别

git合并分支冲突解决