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

wtlkbnrh  于 2023-01-15  发布在  Git
关注(0)|答案(3)|浏览(278)

仓库中有一些文件包含HEAD和另一个提交的合并冲突语法。这些文件不知何故被提交了,我现在无法查看日志。我搜索并找到了在文件上使用“git merge -X theirs”进行合并的命令。但是,这会产生一个错误“file does not pointto a commit”。
我怎样才能自动删除〈〈〈〈〈HEAD到===之间的所有内容,并保留其他提交?手动操作非常困难,因为文件包含70 k行,而且非常繁琐。

q3qa4bjr

q3qa4bjr1#

如果你已经合并并提交了,那么再合并也不会有任何用处。就git所知,你对合并很满意。(你刚才说你对合并不满意,但你不能告诉git。:-))
如果错误的合并没有与其他人共享,最简单也可能是最好的修复方法就是“取消”它,然后重新做一个正确的合并(如果在那之后还有额外的提交,你可以选择那些提交来添加副本到正确的分支中)。
如果错误的合并与他人共享,你仍然可以执行重置/重新合并/挑选顺序,但所有共享此错误的“其他人”都需要知道如何从中恢复。或者,你可以保留错误的合并,但用其他方法修复它。这种情况没有单一的最佳答案。
要想“取消”合并,你首先需要了解git是如何执行合并的,以及分支标签是如何与提交图协同工作的。让我们来画一个示例图片段:

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

在这里,在某个时刻,您有一个main分支名称指向提交C。(或其他人)创建了分支feature。(或其他人)回到分支main并作出两个提交DE,在您(或其他人)处理分支feature并提交了三次FGH的同时。
(Each这些单个字母中的一个代表一个巨大的、丑陋的40个字符的SHA-1 ID,如d1574b852963482d4b482992ad6343691082412f。)
最后,你(或其他人)进入分支main并运行git merge feature。这个合并有很多冲突,但你(或其他人)只是添加并提交了git留下的文件,而不是正确地解决合并。这就是为什么合并提交了M

如果你还没有真正提交,那么提交M就不存在(因此,两个都不能提交I).你所要做的就是运行git merge --abort来停止正在进行的合并.这将给你留下这个图,你在分支main上(不管怎样,我假设;但是,您可能位于分支feature上,在这种情况下,一旦您 do make M,它将位于分支feature上的较低行,而不是位于分支main上的较高行)。

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

如果您打算“取消”合并,* 即使提交M存在 *,这就是您希望在此时结束的图。
即使M存在,也很容易实现,原因是这些分支尖端指针--存储在分支名称中的东西--仅仅指向 * 一些 * 提交,我假设main现在指向提交I,那么,我们可以在图中保留提交MI,但只需使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)两步(到E),并且还重置工作树以匹配给定的提交(再次,提交E:我们只使用名称HEAD~2来命名它)。如果您愿意,可以使用原始SHA-1,您可以使用git log找到它。
请记住,上面的所有内容只是为了让我们回到我们还没有尝试将git merge feature转换为main的情况。我们就能让图看起来像我们想要的那样。
现在我们可以简单地按照我们想要的方式进行合并:

git merge -X theirs feature

这一次,我们应该仔细检查结果以确保工作树中的文件看起来像我们想要的那样。否则我们将再次进行一次错误的合并提交,并回到我们开始的地方。但是让我们假设一切顺利。git merge将成功并实际进行合并提交。以前有一个提交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

因为我们不再关心提交MI

(Note挑选I可能会出错,因为I是在错误的合并M之上构建的。如果失败,则在尝试进行挑选时会出现合并冲突。您必须手动修复此问题。)
注意,上面描述的通过“倒带”分支名称main来“撤消”合并提交M的过程会让共享您的工作的任何人感到头痛(直接使用你的仓库,或者如果你有git push-艾德错误的合并,以便其他人可以看到它,或任何东西). * 他们 * 将不得不收回错误的提交,以及,如果他们自己的工作是基于那些错误的提交,他们可能不得不重复他们的工作。在这种情况下,你可能需要采取不同的方法,通过添加新的提交来修复失败的合并(例如,手动清理混乱)。在这种情况下,那些分享你工作的人会简单地把你的修复作为 fixes,这是Git构建的目的,这样对他们来说就容易多了。

blpfk2vs

blpfk2vs2#

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

git merge -s recursive -X theirs
z31licg0

z31licg03#

如果合并不起作用,尝试回滚冲突

相关问题