2

我有一个包含这些提交的主分支和替代分支:

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,但是这样我有很多冲突要解决。

4

1 回答 1

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)

我们现在面临的一个大问题是,其他人都认为Zmaster分公司的负责人。你不能把你的新东西强加给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-<code>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)

准备好进行最后一击了吗?我们将从 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

应该就是这样!

于 2013-06-17T20:27:52.910 回答