如何与冲突进行 git 合并,以便保留两个更改

  • 本文关键字:保留 两个 冲突 合并 git git
  • 更新时间 :
  • 英文 :


我有两个 PR 将代码添加到同一个文件中f.
在 PR1 中,文件末尾添加了五行代码。 (在第 101-105 行)
在 PR2 中,在同一文件的末尾添加了六个不同的行。(第 101-106 行)

因此,文件f有两个不同的版本PR1->aPR2->b

现在我希望每个 PR 中的代码是可编译的,但它们相互依赖.
我应该先将 PR1 合并到 PR2 中吗? 还是等待拉入主?

如果 PR1 实际上已合并,我应该如何将这些更改放入我的 PR2 中

拉取请求分支不应相互依赖。如果 PR1 被合并,并且在要合并 PR2 时导致合并冲突,只需以对代码有意义的任何方式解决冲突即可。(实现拉取请求的 Web 界面(例如 GitHub)将提供一个界面,您可以在其中执行此操作。

正如 matt 指出的那样,接受两个合并请求(或 GitHub 称之为"拉取请求")的过程一次一步(因为它必须),因此您在主题行中描述的问题实际上还没有出现。 当它确实出现时,在任何编辑器中解决都是微不足道的。

但是,值得一提的是,一般的合并有时会看到这种形式的合并冲突。 也就是说,我们将看到一个可以描述为的冲突:

  • 差异显示在左侧的用户添加了行 A。
  • 差异显示在右侧的用户添加了行 B。
  • 添加的两条线位于同一区域。
  • 我,版本控制系统,不知道要进行哪些更改,如果我同时进行这两项更改,我不知道将它们放入什么顺序

接受两组更改的合并类型通常称为联合合并。 顶级git merge命令没有联合合并选项,但实现单文件合并(并且您可以选择在遇到合并冲突时自行运行的git merge-file)实现了联合合并。

联合合并的问题在于它没有指定将行放入哪个顺序。 如果顺序真的无关紧要,这个"问题"毕竟不是问题,你可以使用联合合并。 如果顺序确实很重要,那就是一个问题,你不应该使用联合合并,它会(明显)随机选择一个订单:因此有 50% 的机会它会选择错误的顺序。

如果可以使用联合合并,只需提取三个输入文件并使用git merge-file即可生成正确的结果。 你从哪里得到三个输入文件? 它们在合并冲突时位于 Git 的索引中。 如果您在计算机上使用 GitHub 而不是 Git 来解决合并冲突,您可能不容易访问这些文件,无论如何,您几乎肯定无法让它们 (GitHub) 运行git merge-file,但如果您在本地、在您自己的笔记本电脑或其他设备上进行合并,请使用git checkout-indexgit show来获取这三个文件。

请注意,git checkout-index有一个特殊选项,旨在同时获取所有三个输入文件:git checkout-index --stage=all。 这意味着--temp选项,因此您必须读取git checkout-index的输出,以了解哪个输出文件与三个输入中的哪个输出一起使用。 然后,您可以使用--union选项运行git merge-file,并将生成的文件放在正确的位置,并使用git add告诉 Git 冲突已解决。

有关其他信息,请参阅git merge-file文档,并记住,当发生合并冲突时,Git 始终将所有输入文件保留在其索引("暂存区域")中,以便您可以解决冲突您的工作是将正确的解析结果放入工作树中,在您希望它显示的任何路径名下,并在该文件上运行git add。 如果路径名与原始路径名相同(通常是),则此git add将从索引中删除三个输入文件,只留下最终结果。

那是:

git merge somebranch
... (message about conflict in path/to/file.ext) ...
my-favorite-editor path/to/file.ext
<fix it up and write it out>
git add path/to/file.ext

git merge步骤:

  • 失败,因此在索引中留下了三个path/to/file.ext副本;1
  • 在名为file.ext的文件夹中,在名为to的文件夹中,在名为path的文件夹中留下了 Git 自己的最佳合并尝试,带有冲突标记;
  • 并在合并过程中停止。

通过在工作树副本上运行编辑器,对其进行编辑以使其正确,将其写出来,然后运行git add,您告诉 Git:

  • 从索引中删除path/to/file.ext的三个副本,以及
  • 放入path/to/file.ext的新副本,处于阶段 0("已解决"),其中包含与名为file.ext的文件夹中名为to的文件夹中名为path的文件夹中的相同数据。

这就是"解决冲突"的真正含义:您只需为下一次提交准备好文件即可。 通常,您可能每天都使用 Git 留在工作树中的尽力而为文件执行此操作。 但是,如果使用编辑器的日常手动过程由于某种原因不令人满意,您也有这种"从 Git 的索引中按原样获取所有三个输入"的方法。git mergetool命令是围绕这个"获取所有三个输入,然后在三个输入上运行编辑器;然后,如果编辑器成功,则运行git add以声明输出正确"序列。


1请注意,这是一个名称中包含斜杠的文件。 不涉及任何文件夹。 这就是path/to/file.ext在 Git 索引中的显示方式;Git 的索引只保存文件,不保存文件夹。

最新更新