压扁提交与其原始提交冲突

时间:2016-04-02 14:22:58

标签: git git-merge merge-conflict-resolution

以下情况是否会产生需要手动解决的冲突?

  1. 您为PR提交了一个功能分支,其中包含提交D,E。

  2. 在审核PR时,您将继续在本地处理相同的功能分支,并添加更多提交F,G,H。

  3. 在某些时候,PR被批准并合并为主人。 Commits D/E on master have been replaced with commit X due to squashing。您现在有一个本地分支,其中包含提交D,E,F,G,H和包含提交X的主分支。

  4. 您希望将提交F / G / H合并到主服务器中。因此,您尝试将本地分支(包含D / E / F / G / H)合并为主分支(包含X)。

  5. 提交D / E和X触摸完全相同的代码行,但具有不同的提交ID。如果一起看D / E并与X比较,它们是相同的。但是,如果单独查看D并与X进行比较,则它们之间存在许多差异,通常是修改后的行。

    git是否足够智能合并{D / E-X}而没有任何合并冲突?或者上面会产生一些需要人工干预的冲突?

2 个答案:

答案 0 :(得分:3)

Git比较自共享基础以来每个提示的更改。相同的变化不会导致冲突。

答案 1 :(得分:3)

我在本地运行了一些git实验,复制了问题中描述的工作流程步骤。不幸的是,答案似乎是肯定的。如果你不是很小心你正在做什么,使用git squash会导致许多合并冲突。

我在this blog post中广泛地写过这篇文章。

如果你做了一个天真的合并,没有任何挤压,就不会发生上述问题。在这种情况下,在合并之后,master和本地分支都将包含提交D-E。因此,下次尝试合并本地D-E-F-G-H分支时,git只需在主服务器上应用F-G-H即可执行合并。

然而,因为我们做了壁球,这最终导致混乱的git。它不是简单地在X之上应用FGH,而是尝试将DEFGH与X合并在一起。不幸的是,因为提交FGH修改了同样由X修改的代码行,所以得到的diff会因合并冲突而失败。

解决此问题的一些可能方法:

  1. 蛮力:将其吸收并手动解决所有冲突。

  2. 一旦提交了pull-request,就不要在pull-request中包含的提交之上开发任何其他提交。从git的角度来看,pull-request中的提交将会消失,所以你不想依赖它们。不幸的是,这意味着您希望在刚刚提交的内容之外进行的任何改进都需要等到您的请求被批准并合并后才能完成。

  3. 如果您在早期的pull-request之上进行了优化,请不要让先前的pull-request合并。而是使用更新的分支提交新的pull-request,或者使用您所做的所有改进覆盖现有的pull-request。不幸的是,这使得拉动请求过程成为一种全有或全无的事情。理想情况下,您可能希望逐步批准/合并初始拉取请求和其他优化。相反,为了防止冲突,你必须强迫自己一次合并整个事物,或者根本不合并任何东西。

  4. 假设您的早期PR已合并,并且您现在还想要合并到master中进行新的改进。而不是尝试将整个分支合并为主分支,而是选择您创建的增量提交,并仅合并那些挑选的提交。因此,在上面给出的示例中,不是尝试将D-E-F-G-H合并到X中,而是选择提交F-G-H,将它们应用于X之上,然后使用生成的分支创建拉取请求。这很有效,可以避免所有冲突,并允许您在任何时间/节奏下进行开发工作。不幸的是,这还需要您手动跟踪D-E == X的事实,并且稍后提交F-G-H需要手动挑选并应用。这需要你花费更多的时间和认知努力,并且通过挑选太多的提交(并且无论如何产生冲突),或者挑选太少的提交(以及缺少重要的改变),也很容易搞乱这一步。 / p>

  5. 避免使用github的squash-on-megre功能。在提交拉取请求之前,要么自己在本地压缩所有提交。或者在没有任何挤压的情况下合并拉动请求。这是大多数项目的现状,并伴随着它带来的所有好处/缺点。

  6. 正如您所看到的,在合并之前压缩所有提交存在一个真正的问题/成本,并且上述解决方案都不是完美的。我不确定上述哪一项是最不可能的。但我确实希望鼓励你更深入地思考这个问题,并意识到利用这个新的令人敬畏的GitHub功能所涉及的警告。