什么是解决错误git合并的最简洁方法

时间:2017-12-01 15:13:50

标签: git merge

我试图帮助我的一个朋友学习git,并且他在合并时添加了源代码文件时犯了一些错误,这样的一些git开销

lines

这是Git树:

import org.junit.Test;

<<<<<<< HEAD
=======

>>>>>>> 7d9b8743f272a230f4079518be7a70a338ea55d8
import static org.junit.Assert.assertEquals;

我通过恢复合并来修复它,然后我不得不手动添加/删除舞台上的一些文件。

有什么建议最好的方法来解决这样的错误合并情况?

1 个答案:

答案 0 :(得分:1)

越早抓住并修复这样的错误,就越好。一旦推出错误的合并,问题就会非常复杂;而且,一旦新工作基于错误的合并,那么更多。

如果您在推送之前意识到合并错误,您可以简单地

git reset --hard HEAD^

再次尝试合并,避免重复之前的错误(例如在提交冲突标记时)。

一旦共享提交并基于它进行更多工作,您必须做出选择。如果您可以与共享回购的每个人协调,您仍然可以获得相同的“干净外观”结果。但我会回过头来看(下面,基于 rebase的方法)。更容易(但不是很好看)的选项是使用新提交(基于revert - 方法)。但是有一个技巧可以做到这一点。

revert - 基于方法:

鉴于您在问题中所展示的内容,您可能已经知道要恢复合并,请使用-m选项(以选择合并应归还的父级)。所以你已经说过了

git revert -m1 id-of-merge-commit

并且您将获得一个新的提交,“撤消”分支中的所有更改。当然,取决于基于合并的其他内容,您可能会遇到冲突。

不仅如此,一旦你有一个干净的还原,git做了一个奇怪的假设:它认为你永远不会想要从那个分支重新集成更改。 (我不认为这是故意的;这是合并计算方式的结果。但无论如何都记录了行为。)

你可以使用一些技巧来解决这个问题。可能最简单的方法是创建一组新的提交,这些提交与原始分支进行相同的更改。如果合并提交是M,那么

git checkout M^2
git checkout -b temp-branch
git rebase -f `git merge-base M^ HEAD``

现在temp-branch有一组新的更改,就像原始分支中的更改一样,在一组新的提交中没有“已经合并”的历史。

git checkout master
git merge temp-branch
# careful this time
git branch -D temp-branch

rebase - 基于方法:

有些事情你可以合理地不喜欢上述内容,所以这里有一个“更清洁”的最终状态(但更难执行)的解决方案:

首先,让每个人都将任何杰出的工作推到一个回购(通常是共享的原产地)。工作不必完全合并,但必须推动所有工作。

那是因为第2步是让每个人都扔掉当地的回购。最后他们会退缩。 (你不是必须这样做,但这是我的建议,因为它比每个人都试图“修复”他们的本地回购更简单。

然后你看看错误合并的第一个父母,并在那里创建一个新的临时分支;在那个分支上,你重做合并而不重复破坏原始合并的任何错误。

现在,基于错误合并的所有内容都必须重新定位到新的良好合并上。如果有多个refs可以从中获得旧的合并,那说起来容易做起来难。此外,如果存在可以从中访问旧合并的新合并,则可能需要使用--preserve-merges rebase选项。但是,如果这些合并中的任何一个有冲突,他们将需要重新解决;更糟糕的是,如果这些合并中的任何一个是“邪恶的”(即使用与默认合并结果不同的TREE提交,即使默认合并将彻底解决),那么rebase将没有产生正确的结果。

所以当一切都完成后,你会想要做一些diff来验证结果,假设你成功导航了所有这些,你就可以让每个人重新克隆。

你可以看到为什么,即使它很丑陋,基于revert的方法通常也是公认的妥协。