合并错误时恢复丢失的提交 [英] Restore lost commits when a merge was done wrong

查看:110
本文介绍了合并错误时恢复丢失的提交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

什么是更好的方法来做到这一点?

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

我正在考虑做git rebase ,但以这种方式我有很多冲突要解决。

解决方案

重新解决问题



所以你目前的回购状态是:

  A --- B --- C  -  -  D ------ 
\\
E --- F --- G ---(M)--- H ---我--...-- Z(主)

但合并不是成功,所以 C & D
未正确合并到当前主分支中。



无法完成(不会造成痛苦)



不幸的是,您将无法达到以下状态:

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

不会对每位已经取消当前主人的人造成问题
分支到自己的回购中。



所有不会丢失



有很多方法可以达到类似的结果(但是我不能保证不会有任何合并冲突)。从你的意见,我是
会假设你知道失踪提交的参考。为方便起见,
我也假定您已经标记了以下提交:

  $ git tag< ref -to-d取代; oldmaster 
$ git标签< ref-to-G> premerge
$ git标签< ref-to-H> postmerge



丢失年表



如果你并不关心维护提交的年代表(即
A --- B --- C --- D --- E --... rebase到当前 master

 
$ git rebase master
#处理任何合并冲突

$ git push origin master
#在其他任何人进一步扩展分支之前先把它拿出来!

如果一切顺利,您的分支现在看起来像:

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



超越冲突的痛苦吗?



如果你真的想维护年表,我们尝试重新绑定到旧的
master

< (取决于它如何失败,原来的合并可能会导致这个
方法出现问题)如果是这样,我们将在第三种方法中处理这个问题)

  $ git checkout master 

$ git rebase oldmaster
#处理任何合并冲突

这是您担心的冲突时间......但它可能不是
痛苦的时刻。 Git通常非常擅长应对分支之间的差异,
,所以在这里可能不需要太多人工干预。



一旦完成,您的分支将看起来像这样:

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

我们现在面临的最大问题是每个人else认为 Z
master 分支的头部。你不能强迫你的新的 master 放到其他人身上,没有
会导致很多痛苦和痛苦。可能现在要做的最好的事情是:

  $ git merge -s我们的原点/主
#两个主分支之间的合并提交,但文件
#的内容将与我们的新主分支相同

$ git push origin master



$ b

现在图片应该是:

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



循序渐进



也许你喜欢以前的结果,但是有太多的冲突。
或者,也许前一次失败的合并提高了丑陋的头部并导致了问题。



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

  $ git checkout oldmaster 

$ git rebase premerge
#记住我假设你已经标记了那些refs?
#处理任何合并冲突

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

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

我们将跳过merge commit并尝试引入ħ - ž
因为你在这里,我感觉有点谨慎,所以我要首先在
中带入 H
p>

  $ git cherry-pick postmerge 
#处理任何合并冲突

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

树现在应该如下所示:

  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我们的主人






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

因为我们正在处理 oldmaster 分支,我们需要在返回之前快速转发
真正的 master 分支

  $ git checkout master 
$ git merge oldmaster
#快进合并

$ git push origin master

那应该是t帽子!


I have a master and alternative branch with these commits :

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

Something wrong happened when the merge was done and some commits were lost, and people continuous to commit on branch:

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

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

What is the better way to do that ?

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

I am thinking to do git rebase, but in this way I have a lot of conflicts to resolve.

解决方案

Restating the problem

So the current state of your repo is:

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

But the merge was not successful, so the changes represented by C & D are not properly incorporated into the current master branch.

Can't be done (without causing pain)

Unfortunately you will not be able to reach the following state:

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

without causing problems for every person who has pulled the current master branch into their own repo.

All is not lost

There are, however, a number of ways you could achieve a similar result (but I can't promise there won't be any merge conflicts). From your comments, I am going to assume you do know the refs for the missing commits. For convenience, I am also going to assume you have tagged the following commits:

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

Lose the chronology

If you don't really care about maintaining the chronology of the commits (ie A --- B --- C --- D --- E --...) the easiest route would probably be to rebase onto the current 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!

If all goes to plan, your branch will now look like:

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

Overstating the pain of conflict?

If you really want to maintain the chronology, let's try rebasing onto the old master:

(depending on how it failed, the original merge may cause problems for this approach. If so, we'll deal with that in the third approach)

$ git checkout master

$ git rebase oldmaster
  # deal with any merge-conflicts

This is the time of conflicts which you feared... but it may not be that painful. Git is usually very good at coping with differences between branches, so there may not be much manual intervention required here.

Once that is done, your branch will look like this:

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

The big problem we now face is that everyone else thinks Z is head of the master branch. You can't force your new master onto other people, without causing much pain and suffering. Probably the neatest thing to do now would be:

$ 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

Now the picture should be:

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

Take it step by step

Maybe you liked the previous results, but there were just too many conflicts. Or maybe that previous failed merge raised its ugly head and caused problems.

Let's try one final approach, taking it in smaller steps. First of all, let's create the branch which we should have had at the time of the original merge:

$ git checkout oldmaster

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

We should now be looking at this state:

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

We are going to skip that merge commit and attempt to bring in commits HZ. Because you're here, I'm feeling a little cautious so I'm going to bring H in on its own first:

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

If there are going to be any difficult conflicts, they will probably be here. You will still need to resolve them, but at least they only represent one commit (he says, knowing he doesn't have to merge them himself!).

The tree should now look like:

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

Ready for the final push? We're going to bring in the remaining commits from master then, as before, create a merge commit so we can safely bring the other users onto the new branch:

$ git cherry-pick postmerge..master

$ git merge -s ours master

This should result in:

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

Because we were working on the oldmaster branch, we'll need to fast-forward the real master branch before pushing back:

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

$ git push origin master

And that should be that!

这篇关于合并错误时恢复丢失的提交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆