修复已提交的未解决的合并冲突

时间:2014-08-12 09:33:42

标签: git merge merge-conflict-resolution

存储库中有一些文件包含与HEAD和另一个提交的合并冲突语法。那些文件以某种方式提交,我现在无法查看日志。我搜索并找到了与" git merge -X他们合并的命令"在文件上。但是,这会产生错误"文件不指向提交"。

如何自动删除<<<<<< HEAD ====并在每种情况下保留其他提交?手动执行此操作非常困难,因为文件包含70k行,这将非常繁琐。

2 个答案:

答案 0 :(得分:1)

如果您已经合并并提交,重新合并将不会做任何有用的事情。就git所知,你对合并感到满意。 (你只是说你对它很满意,但是你不能告诉它git。:-))

如果不与其他任何人共享错误的合并,那么最简单也可能是最好的解决方案是" un-do"它,然后重新做它作为纠正合并。 (如果之后还有其他提交,您可以挑选这些提交以将副本添加到更正的分支。)

如果错误合并 与他人共享,您仍然可以执行重置/重新合并/挑选序列,但所有这些"其他"谁分享这个需要知道如何从中恢复。或者,您可以保留不良合并,但以其他方式修复它。对于这种情况,没有一个最好的答案。

To" un-do"合并时,您需要了解git如何首先进行合并,以及分支标签如何与提交图一起使用。让我们绘制一个样本图片段:

... - C - D - E ----- M - I  <-- main
        \           /
          F - G - H          <-- feature

在这里,您在某个时候有一个指向提交main的{​​{1}}分支名称。您(或其他人)创建了分支C。然后你(或其他人)回到分支feature并进行了两次提交mainD,同时你(或其他人)在分支{{1}上工作并提交了三次提交EfeatureF

(这些单个字母中的每一个都代表{x 1}这样一个丑陋的40个字符的SHA-1 ID。)

最终,您(或其他人)加入了分支G并运行H。这个合并有一堆冲突,但你(或其他人)只是添加并提交了git留下的文件的混搭,而不是正确解析合并。这就是合并提交d1574b852963482d4b482992ad6343691082412f

的原因

如果您尚未实际提交,则提交main不存在(因此,两者都不能提交git merge feature)。您所要做的就是运行M以停止正在进行的合并。这将留下你的这个图,你在分支M(我假设,无论如何;你可能在分支I,在这种情况下,一旦你 make git merge --abort,它位于分支main上,位于下方,而不是位于上方的分支feature上。

M

如果您打算&#34;取消&#34;这是您想要在此时结束的图表。合并,即使提交feature存在

即使存在main,也很容易到达那里。原因是这些分支尖指针 - 存储在分支名称中的东西 - 仅指向某些提交。我假设... - C - D - E <-- main \ F - G - H <-- feature 现在指向提交M。好吧,我们可以在图表中保留提交Mmain,但只需让I指向再次提交M

I

我们首先要确保通过使一些标签(分支或标签名称)指向它来保存提交main的标识。也就是说,让我们填写三个问号。我们可以使用E

为此制作标记
... - C - D - E              <-- main
       \       \
        \       `--- M - I   <-- ???
         \          /
          F - G - H          <-- feature

或与I分支。任何一个都可以正常工作。

现在我们只需要将git tag指回git tag save-main main ,就像在图纸中一样。最简单的方法是使用剪切粘贴或倒计时。在这种情况下,倒计时显示两次跳回会让我们到git branch(一跳回到我们main),所以:

E

将当前分支(即E)移回图中的两个步骤(到M),并重新设置工作树以匹配给定的提交(再次,提交git reset --hard HEAD~2 :我们只使用名称main来命名它。如果您愿意,可以使用原始SHA-1,您可以使用E找到它。


请记住,上述所有内容只是让我们回到我们尚未尝试E进入HEAD~2的情况。我们现在已经做到了;我们的图表看起来就像我们想要的那样。

现在我们可以按照我们想要的方式进行合并:

git log

这一次,我们应该仔细检查结果,以确保工作树中的文件看起来像我们想要的那样。否则,我们将再次进行搞砸合并提交,并回到我们开始的地方。但是,让我们假设它一切顺利。 git merge feature将成功并实际进行合并提交。曾经有一个提交main,这是一个不同的提交,git merge -X theirs feature 仍然存在 - 我们的git merge标记指向{{1} }和M指向M - 所以我们现在拥有的图表有一个新的合并save-main

I

作为我们的最后一步,我们可能希望通过将I复制到新的提交M来从M2恢复这些内容。为此,我们只需使用... - C - D - E ---- M2 <-- main \ \ / \ `--/- M - I <-- save-main \ | / F - G - H <-- feature

即可
I

名称I指向提交I',因此这会复制我们在git cherry-pick中执行的任何操作,并将其添加到我们当前的分支git cherry-pick save-main

save-main

现在我们已完成名称I,所以我们可以删除它:

I

因为我们不再关心提交main... - C - D - E ---- M2 - I' <-- main \ \ / \ `--/- M - I <-- save-main \ | / F - G - H <-- feature

(请注意,挑选save-main可能会出错,因为git tag -d save-main 是在错误合并M之上构建的。如果它失败了,你会得到一个尝试做樱桃选择时合并冲突。你必须手动解决这个问题。)


请注意上述过程,&#34;取消&#34;合并提交I by&#34;倒带&#34;分支名称I会导致分享您工作的任何人头痛(直接使用您的存储库,或者如果您有I - 那么其他人可以看到它,或者其他什么)。 他们也必须撤回不良提交,如果他们将自己的工作建立在那些糟糕的提交上,他们可能不得不重复他们的工作。在这种情况下,您可能希望采用不同的方法,通过添加简单修复失败的合并的新提交(例如,手动清理混乱)。在这种情况下,那些分享您工作的人只会选择修复修复,这是git构建的内容,因此对他们来说会更容易。

答案 1 :(得分:0)

根据git-merge documentationtheirs是一个有效的命令,但在这种情况下您可能还需要明确指定递归策略:

git merge -s recursive -X theirs