存储库中有一些文件包含带有HEAD和另一个提交的合并冲突语法。这些文件已以某种方式提交,我现在无法查看日志。我搜索并找到了与文件上的“ git merge -X他们的”合并的命令。但是,这会产生错误“文件未指向提交”。
如何自动删除<<<<< HEAD到====的所有内容,并在每种情况下保留其他提交?手动执行此操作非常困难,因为文件包含70k行,这将非常繁琐。
如果您已经合并并提交,重新合并将无济于事。据git知道,您对合并感到满意。(你刚才说你不喜欢它,但你不能告诉给饭桶。:-))
如果不良合并没有与其他任何人共享,则最简单且可能最好的解决方法是“撤消”它,然后将其作为更正的合并重新进行。(如果此后还有其他提交,则可以挑选那些提交以将副本添加到更正的分支中。)
如果不良合并是与他人共享的,您仍然可以执行重置/重新合并/ cherry-pick序列,但是所有共享此错误的“其他”都需要知道如何从中恢复。或者,您可以保留不良合并,但以其他方式解决。对于这种情况,没有最佳的答案。
要“撤消”合并,您首先需要了解git如何进行合并,以及分支标签如何与提交图一起使用。让我们绘制一个示例图片段:
... - C - D - E ----- M - I <-- main
\ /
F - G - H <-- feature
在某些时候,您这里有一个main
指向commit的分支名称C
。您(或其他人)创建了branch feature
。然后,你(或其他人)回到分支main
并取得两次提交D
,并E
为您(或他人)的工作分支,同时feature
并提出三个提交F
,G
和H
。
(这些单个字母中的每个字母代表一个大的丑陋的40个字符的SHA-1 ID之一,例如d1574b852963482d4b482992ad6343691082412f
。)
最终,您(或其他人)进入了分支main
并开始奔跑git merge feature
。这种合并有很多冲突,但是您(或其他人)只是添加并提交了git留下的文件杂乱的杂物,而不是正确地解决了合并问题。这就是合并提交的原因M
。
如果您尚未实际提交,则提交M
不存在(因此,都不能提交I
)。您要做的就是git merge --abort
停止正在进行的合并。这样一来main
,您就可以在这张图上,也可以在分支上(无论如何,我都认为;feature
尽管您可能会在分支上,在这种情况下,一旦执行make M
,它就会在分支feature
上,在下一行而不是在branch上main
,在上方)。
... - C - D - E <-- main
\
F - G - H <-- feature
如果您打算“撤消”合并,即使提交M
存在,这也是您要在此结束的图形。
即使M
存在,也很容易到达那里。原因是这些分支提示指针(存储在分支名称中的内容)仅指向某些提交。我假设main
现在指向commit 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
)移到图表中的两步(到E
),并重新设置工作树以匹配给定的提交(再次,commit 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
到新的commit来还原内容I'
。为此,我们可以简单地使用git cherry-pick
:
git cherry-pick save-main
该名称save-main
指向commit 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
和I
更多。
(请注意I
,由于采摘I
是在错误合并的基础上进行的,因此采摘可能会出错M
。如果失败,尝试进行采摘时会出现合并冲突。您必须手动解决此问题。 )
请注意,上述M
通过“回退”分支名称来“撤消”合并提交的过程main
,对于共享您的工作的任何人(直接使用您的存储库,或者如果您编辑git push
了错误的合并,从而使所有人感到头痛),其他人可以看到它,等等)。他们也将不得不撤消错误的承诺,如果他们基于那些错误的承诺开展工作,则可能不得不重复他们的工作。在这种情况下,您可能希望采用不同的方法,即添加新的提交以简单地修复失败的合并(例如,手动清理混乱)。在这种情况下,那些与您共享工作的人只会将您的修订作为fix,这是git要做的事情,因此对他们来说更容易。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句