我有两个 PR 将代码添加到同一个文件中f
.
在 PR1 中,文件末尾添加了五行代码。 (在第 101-105 行)
在 PR2 中,在同一文件的末尾添加了六个不同的行。(第 101-106 行)
因此,文件f
有两个不同的版本PR1->a
和PR2->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-index
或git 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 的索引只保存文件,不保存文件夹。