很多令人困惑的 git 冲突

Lots of confusing git conflicts

在 bitbucket 的拉取请求期间,我遇到了一个非常令人困惑的冲突问题。我有 137 个冲突,如下所示。如何解决它并防止将来发生这种情况?这是 Android Studio 在 macOs 上的项目。

如您所见,我刚刚添加了一些行,但 git 将其视为冲突。

您可以在下面找到与 merge.conflictStyle=diff3 的冲突。

我仍然不知道为什么它是冲突而不是版本。

您的 diff3 屏幕截图提供了答案。 (另外:不要在此处使用屏幕截图。直接剪切并粘贴 文本 。在这种情况下,应该删除带有行号的装订线信息,但这没关系。请参阅 How do I ask a good question.)

请记住,在 Git 中,合并 是关于合并工作。涉及 三个 次提交:

  • 您在您的分支上开始了一些提交。 Git 将其称为 合并基础 提交。

  • 他们在他们的分支上从这个完全相同的提交开始

所以 Git 第一个 运行s 两个 git diff 命令(或者内部等效命令)。一个将此合并基础与 您的 版本的代码进行比较,第二个 git diff 将此合并基础与 他们的 版本的代码进行比较.

我先从中间冲突说起

diff3 样式 diff 包括合并基本代码(来自提交 ce442625),我们可以在其中阅读——我重新输入了这个,所以我可能添加了一些拼写错误1—原始行说:

    chage_lang.setOnClickListener { openDialogToSelectLang() }

这显然有缺陷:它应该读作 change_lang 而不是 chage_lang

您的 提交中,在 HEAD 中,您保留了这一行,但在它之后又添加了一个空行。这是一个“差异大块头”。

他们的提交中,在feature/dark_mode他们修正了拼写并替换了 一个非空行的单空行,得到:

    change_lang.setOnClickListener { openDialogToSelectLang() }
    change_theme.setOnClickListener { openDialogToSelectTheme() }

这里Git不知道是保留你添加的空行,还是保留他们删除替换的空行;它不知道是保留错误的拼写 chage_lang,还是使用更正的拼写 change_lang。所以它产生了一个冲突:你必须select正确的分辨率。

在此之下,最后一个冲突类似:merge base 版本说:

    android:layout_marginTop="@dimen/standard_margin"
    android:background="@color/white"

您的版本中,您*将第一行"更改为"8dp"并且保持第二行不变,但在他们的版本他们原封不动的保留了第一行,删掉了第二行。再一次,Git不知道要不要拿你的版本、他们的版本、两者的某种组合,或者什么。必须在此处选择正确的分辨率。

第一个 diff 是最令人困惑的:在这里,从合并基础版本中提取的行集是empty。你这边的变化是加了一个空行,而他们加了一个非空行阅读:

    setBackgroundColor(ContextCompat.getColor(context, ...

与其他两种情况一样,Git 不知道是否应该添加您的空白行,或他们的行,或两者,或两者都不添加,或什么。 必须选择。

编辑有问题的文件以获得正确的组合(并且不再包含冲突标记),或使用合并工具来达到相同的效果。然后在生成的文件上使用 git add,或者使用合并工具——可能是同一个合并工具,全部作为一个东西——为你 运行 git add . git add 更新 Git 的 暂存区 中的文件副本,以便 Git 知道正确的分辨率。

(Git 假设你告诉它的是正确的, 正确的,所以一定要在这里告诉它正确的事情!换句话说,确保整个文件是正确的。通常这意味着您应该测试您的合并分辨率,然后再将其提供给Git。这是我不这样做的原因之一不喜欢git mergetool:你做合并,然后git mergetool马上告诉Git是对的,如果不对就得重新开始2)


1这种拼写错误的风险是为什么“询问”页面建议使用剪切和粘贴。

2你可以只用这个文件重新开始,and/or编辑和调试它而不用重新创建冲突,但现在更难看到了原来的三个输入文件。使用 git checkout -m 重新创建冲突是可行的,但这会失去您的解决方案。一旦你 确切地 你和 Git 在做什么,所有这些都有解决方法,但总的来说,整个用户体验对我来说似乎很糟糕。