简体   繁体   English

Git:如何“撤消”合并

[英]Git: How to “undo” a merge

The situation: Starting with the Master at A I branched and made some changes at B then merged that branch back in (C) . 情况:从A分支开始,我分支并在B处做了一些更改然后将该分支合并回(C) After making some more changes I was at D but found I needed to deploy the code without the changes that happened in the branch. 在进行了一些更改后,我在D但发现我需要部署代码而不需要在分支中发生更改。 If I hand't merged it that would have been fine. 如果我不合并它本来没问题。

A_______C___D
 \     /
  \_B_/

Firstly I'd like to know what I should have done from here to deploy the code as if the merge never happened. 首先,我想知道我应该从这里做什么来部署代码,好像合并从未发生过一样。 Note: none of the same files that were edited in the branch have been edited in the master. 注意:没有在分支中编辑的相同文件在主服务器中编辑过。

Secondly... 其次...

I didn't have time to work out the best method to deal with this, so I deleted the files which the branch added, and manually reverted a few edits made in the branch then commited the result for deployment ( F ) 我没有时间找出处理这个问题的最佳方法,所以我删除了分支添加的文件,并手动恢复了分支中的一些编辑,然后提交了部署结果( F

A_______C___D___F
 \     /
  \_B_/

I want to be able to keep developing the branch and merge any changes from the master into it to keep it up to date, but if I do that the stuff I did to create F will be merged in and cause the files to be deleted and the edits to be reverted. 我希望能够继续开发分支并将来自主服务器的任何更改合并到其中以使其保持最新,但如果我这样做,我创建的F所做的事情将被合并并导致文件被删除要还原的编辑。 What is the best way to deal with this? 处理这个问题的最佳方法是什么?

You can use rebase to do that in one step: 您可以使用rebase一步完成:

git rebase --onto A C D

I just tested this, with appropriate results: 我刚测试了这个,并得到了适当的结果:

$ edit test.txt
$ git add .
$ git commit -mA
$ git checkout -b the_branch
$ edit test.txt
$ git commit -a -mB
$ git checkout master
$ git merge master the_branch --no-ff
$ edit test.txt
$ git commit -a -mD

From here you have the situation you described. 从这里你可以了解你描述的情况。 Then: 然后:

$ git rebase --onto <SHA1-for-A> <SHA1-for-C> master

rebases commits from C (excluded) to master, onto A. I needed to fix some conflicts since I modified at the same places in B and D, but I think you won't. rebase从C(排除)提交到master,转到A.我需要修复一些冲突,因为我在B和D的相同位置进行了修改,但我认为你不会。

   _D'
  /
 /
A_______C___D
 \     /
  \_B_/

Doc about git rebase --onto , which is more or less your situation: http://git-scm.com/docs/git-rebase 关于git rebase --onto ,这或多或少是你的情况: httpgit rebase --onto


If you had: 如果你有:

A_______C___D___F
 \     /
  \_B_/

, then you have now: ,那你现在有:

   _D'___F'_(master)
  /
 /
A_______C___D___F
 \     /
  \_B_/(the_branch)

From here, merging the changes in master into the branch is easy. 从这里开始,将master中的更改合并到分支中很容易。 Discard the commit F' altogether. 完全丢弃提交F'

$ git checkout master # if you were not here already
$ git branch old_fix  # if you want to be able to return to F' later
$ git reset --hard <SHA1-to-D'>

After the commands above you have: 在上面的命令之后你有:

     (master)
    /
   _D'___F'_(old_fix)
  /
 /
A_______C___D___F
 \     /
  \_B_/(the_branch)

To merge updates of master into the_branch: 要将master的更新合并到the_branch中:

$ git checkout the_branch
$ git merge master

... and fix the conflicts. ......并解决冲突。

The obvious solution is to reset to A , reapply all patches manually and resolve conflicts (which you won't have). 显而易见的解决方案是重置为A ,手动重新应用所有补丁并解决冲突(您不会拥有)。

Alternatively you can just git revert patch B but that will create a new commit. 或者你可以只是git revert补丁B但这将创建一个新的提交。

Although Gauthier's answer is better. 虽然Gauthier的答案更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM