【问题标题】:Is `git merge` able to display every change (w.r. to a common ancestor) as merge conflict?`git merge` 是否能够将每个更改(对于共同祖先)显示为合并冲突?
【发布时间】:2017-01-23 07:42:50
【问题描述】:

假设我们有一个文件common_ancestor (master)

ok
ok
ok
ok
ok

从那里,我们将master 更改并提交到

ok
change not ok (looking back)
ok
ok
ok
latest change
ok

现在我们有了一个更好的主意,结帐common_ancestor 并将其更改为

ok
ok
ok
This is a really good change
ok
ok

并在新分支dev 中提交。由于我需要master 的一些开发,我想将dev 合并到master 但我想决定是否保留每个更改。我试过了

git checkout master
git merge dev --no-ff --no-commit

但我没有得到我expected 的内容。我正在寻找的是这样的:

ok
<<<<HEAD
change not ok (looking back)
====
>>>> HASH
ok
ok
<<<<HEAD
====
This is a really good change
>>>> HASH
ok
<<<<HEAD
latest change
====
>>>> HASH

冲突标记可见(参见here)。

编辑:我所看到的,git merge dev --no-ff --no-commit 没有突出显示更改 - @VonC 解释了为什么没有可见的冲突标记(因为没有冲突!)。

【问题讨论】:

标签: git merge


【解决方案1】:

在您的情况下,将 dev 合并到 master 将简单地:

  • 添加来自dev的更改“This is a really good change
  • 保留master "change not ok (looking back)" 中引入的更改

这是因为这些更改不是在文件中的同一位置进行的:同一行没有并发修改。
这意味着没有冲突。

如果您想在合并后查看(但在合并之前提交),请can set up a custom merge driver

[merge "verify"]
        name = merge and verify driver
        driver = ./merge-and-verify-driver %A %O %B

您可以将该驱动程序与.gitattributes file 中的文件相关联。

*.R merge=merge and verify driver

使用merge-and-verify-driver.sh 的脚本始终返回 1,以表明存在冲突,即使合并实际上是在没有冲突的情况下解决的(这里的情况是:合并中没有冲突)。

#!/bin/bash
git merge-file "${1}" "${2}" "${3}"
exit 1

注意:如果发生冲突,您将获得更多信息:

git config --global merge.conflictstyle diff3

【讨论】:

  • 查看并发修改示例:stackoverflow.com/a/38989749/6309
  • 我现在了解缺少的冲突标记。如果我所有的文件都是.R 文件怎么办?我如何告诉 git,对于特定文件,我想先“审查”?如果我正确理解您链接中的答案,他们会在 git 属性中指定文件扩展名。像git merge --verify dev 这样的自定义命令可能吗? (我很抱歉,如果这个问题很愚蠢 - 我对 git 很陌生。)
  • @Christoph 在 .gitattribute 中,您可以将自定义合并驱动程序与文件类别相关联(如 gist.github.com/dpwright/2657379)我已经编辑了我的答案。
  • 但是,我所有的.R 文件都“需要审查”,也就是说,我无法决定是否要查看合并? (背景:在大多数(!)情况下,git 完全按照人们的意愿行事——如果我让 git 变得更糟/更慢,那就太糟糕了)
  • @Christoph 实际上,使用该合并驱动程序,将发生合并,而不是合并提交。这使您有机会在添加和提交所有内容之前仅查看所需的文件。
【解决方案2】:

正如@VonC 所指出的,将两个版本的差异视为冲突是不正确的。因此他回答了我的问题。为了达到我的目标,我使用了

git difftool -t=kdiff3 dev master

以及其中的合并工具。在 kdiff3 中,每个差异都会突出显示,您可以为要保留的每一行选择哪个版本。 另请参阅 here 以获取视频教程。

【讨论】:

  • 是的,kdiff3 在这里很有用。一旦合并完成(但未提交),您可以在任何修改过的文件上使用 git diff,如果需要,kdiff3 将允许您完成合并。
【解决方案3】:

我想将 dev 合并到 master 但我想为每次更改决定是否保留。

这需要交互式变基:

git branch dev_rebase dev
git checkout dev_rebase
git rebase -i master

然后从那里继续。 git help rebase,寻找“交互模式”应该会给你一些想法。只需删除您想跳过的行(提交),如果您想进行部分提交但需要编辑文件,请使用 edit

如果出现严重错误,dev 无论如何都不会受到影响。

# if happy:

git checkout master
git merge --no-ff dev_rebase

# for good measure:

git checkout dev
git rebase master

【讨论】:

  • 我担心我用 git 工作的时间不够长:你如何进行?当我在 git bash 中输入命令时,会打开一个奇怪的编辑器(MINGW64),我迷路了。见编辑...
  • 在该编辑器中,git 列出所有提交(从 master 到当前分支的尖端)。如果您只是退出它,git 将重播所有提交,您将在开始的地方结束。神奇之处在于编辑该文件 - 您可以删除行(那些提交将被跳过),您可以重新排序(提交将以不同的顺序应用),或者您可以将命令 pick 替换为其他内容,例如 @ 987654327@。 git help rebase 更详细地解释了它。
  • 我认为你的方法是不同的,因为 rebase 也为你做了合并 - 请参阅下面的答案以及我最后做了什么。如果我错了,请告诉我,然后我会再看一遍。
猜你喜欢
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多