2010-12-14 117 views
16

这种情况: 我开始在主人A我分支并在B做了一些更改,然后合并该分支回(C)。在做了一些更改后,我在D,但发现我需要部署代码而没有在分支中发生的更改。如果我没有把它合并,那会很好。Git:如何“撤消”合并

A_______C___D 
\ /
    \_B_/ 

首先,我想知道我应该在这里做,好像合并从来没有发生在代码部署。注意:在分支中编辑的相同文件都没有在主文件中编辑过。

其次...

我没有时间来解决处理这个是最好的方法,所以我删除该分支添加的文件,并手动恢复分支,然后做一些修改COMMITED部署的结果(F

A_______C___D___F 
\ /
    \_B_/ 

我希望能够继续开发该分支与合并从主任何更改到它保持它最新的,但如果我这样做的东西,我做创建F将被合并并导致文件被删除并且编辑被恢复。处理这个问题的最佳方法是什么?

回答

16

您可以使用衍合做,在一个步:

git rebase --onto A C D 

我只是测试这一点,适当的结果:

$ 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 

从这里,你有你所描述的情况。 然后:

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

底垫从C(除外)提交掌握,到A. 我需要解决一些矛盾,因为我修改了在B和d相同的地方,但我想你不会。

_D' 
/
/
A_______C___D 
\ /
    \_B_/ 

文件约git rebase --onto,这或多或少是您的情况: http://git-scm.com/docs/git-rebase


如果您有:

A_______C___D___F 
\ /
    \_B_/ 

,那么你现在有:

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

从这里,将master中的更改合并到分支中很容易。完全放弃提交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'> 

你上面的命令之后有:

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

要合并主的更新到the_branch:

$ git checkout the_branch 
$ git merge master 

...和解决冲突。

+0

太棒了,谢谢!我将来会使用它(如果我的合并更加小心,将无法正常工作)。请参阅@ terminus为我所做的答案。我认为它和你的答案达到了几乎相同的结果。 – Jake 2010-12-15 00:53:11

6

显而易见的解决方案是重置为A,手动重新应用所有修补程序并解决冲突(您不会有)。

或者,您也可以只为git revert补丁B但这会创建一个新的提交。

虽然Gauthier的回答比较好。

+0

谢谢,在阅读本文后,我看着补丁,并最终在这里:http://www.gitready.com/intermediate/2009/03/04/pick-out-individual-commits.html所以我分支A和樱桃采摘的D和F,然后将结果合并到原始分支中以使其更新。 – Jake 2010-12-15 00:52:43

+0

你真的樱桃F?我以为F只是为了逆转B和C,所以在C'之后没有任何事情要做? – Gauthier 2010-12-15 10:03:39

+0

对不起,现在我不确定。也许我做了但没有真正需要。 – Jake 2011-01-05 07:29:06