合并错误时恢复丢失的提交

时间:2013-05-06 15:16:40

标签: git

我有一个主要和替代分支与这些提交:

A --- B --- C --- D (master)
       \
        E --- F --- G (sprint1)

当合并完成并且一些提交丢失,并且人们不断在分支上提交时发生了错误:

A --- B --- E --- F --- G --- (M) (master)

A --- B --- E --- F --- G --- (M) --- H --- I (master)

有什么更好的方法呢?

A --- B --- C --- D --- E --- F --- G --- H --- I

我正在考虑做git rebase,但这样我就有很多冲突需要解决。

1 个答案:

答案 0 :(得分:0)

重述问题

因此您的回购的当前状态是:

A --- B --- C --- D ------
       \                  \
        E --- F --- G --- (M) --- H --- I --...-- Z (master)

但是合并没有成功,所以C& D是 未正确纳入当前master分支。

无法完成(不会引起疼痛)

很遗憾,您将无法达到以下状态:

A --- B --- C --- D --- E' --...-- Z' (master)

不会给每个拔出当前人master造成问题 分支到他们自己的回购。

一切都没有丢失

然而,有很多方法可以达到类似的效果(但是我 不能保证不会有任何合并冲突)。从你的评论中,我是 假设你知道缺少提交的引用。为了方便, 我还假设你已经标记了以下提交:

$ git tag <ref-to-D> oldmaster
$ git tag <ref-to-G> premerge
$ git tag <ref-to-H> postmerge

失去年表

如果你真的不关心保持提交的年表(即 A --- B --- C --- D --- E --...)最简单的路线可能是 重新定义到当前的master

$ git checkout oldmaster

$ git rebase master
  # deal with any merge-conflicts

$ git push origin master
  # get it out there before anyone else extends the branch further!

如果一切按计划进行,您的分支现在将如下所示:

A --- B --- E --- F --...-- Z --- C' --- D' (master)

过分冲突的痛苦?

如果你真的想要保持年代表,那就让我们尝试一下旧版 master

(取决于它失败的原因,原始合并可能会导致此问题 做法。如果是这样,我们将在第三种方法中处理这个问题)

$ git checkout master

$ git rebase oldmaster
  # deal with any merge-conflicts

这是你担心的冲突时间......但可能不是那样 痛苦。 Git通常非常善于应对分支之间的差异, 所以这里可能没有太多人工干预。

完成后,您的分支将如下所示:

A --- B --- C --- D -------- E' --- F' --...-- Z' (master)
       \                  \
        E --- F --- G --- (M) --- H --...-- Z (origin/master)

我们现在面临的一个大问题是,其他所有人都认为Z是其中的负责人 master分支。没有,你不能强迫你的新master加入其他人 造成很多痛苦和痛苦。可能现在要做的最好的事情是:

$ git merge -s ours origin/master
  # this creates a merge commit between the two master branches, but the file
  # contents will be identical to our new master branch

$ git push origin master

现在的图片应该是:

A --- B --- C --- D -------- E' --- F' --...-- Z' --- (M2) (master)
       \                  \                           /     (origin/master)
        E --- F --- G --- (M) --- H --...-- Z --------

一步一步地进行

也许你喜欢以前的结果,但冲突太多了。 或者也许之前失败的合并引起了丑陋的头脑并引发了问题。

让我们尝试最后一种方法,以较小的步骤进行。首先,让我们来吧 创建我们原始合并时应该拥有的分支:

$ git checkout oldmaster

$ git rebase premerge
  # remember I "assumed" you had tagged those refs?
  # deal with any merge-conflicts

我们现在应该看看这个状态:

A --- B --- C --- D -------- E' --- F' --- G' (oldmaster)
       \                  \
        E --- F --- G --- (M) --- H --- I --...-- Z (master)

我们将跳过该合并提交并尝试引入提交H - Z。 因为你在这里,我感到有些谨慎,所以我要带上H 首先是:

$ git cherry-pick postmerge
  # deal with any merge-conflicts

如果有任何困难的冲突,他们可能会在这里。 你仍然需要解决它们,但至少它们只代表一个 承诺(他说,知道他不必自己合并!)。

树现在看起来像:

A --- B --- C --- D -------- E' --- F' --- G' --- H' (oldmaster)
       \                  \
        E --- F --- G --- (M) --- H --- I --...-- Z (master)

准备好最后的推动?我们将引入剩余的提交 然后,像以前一样,创建一个合并提交,这样我们就可以安全地带来另一个 用户进入新分支:

$ git cherry-pick postmerge..master

$ git merge -s ours master

这应该导致:

A --- B --- C --- D -------- E' --- F' --...-- Z' --- (M2) (oldmaster)
       \                  \                           /
        E --- F --- G --- (M) --- H --...-- Z --------
                                           (master)

因为我们正在oldmaster分支机构工作,所以我们需要快进 在推回之前真正的master分支:

$ git checkout master
$ git merge oldmaster
  # fast-forward merge

$ git push origin master

那应该是那个!