Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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). 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. 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)

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. What is the best way to deal with this?

like image 993
Jake Avatar asked Dec 14 '10 00:12

Jake


People also ask

How do I undo a merge in git?

In case you are using the Tower Git client, undoing a merge is really simple: just press CMD+Z afterwards and Tower will undo the merge for you!

How do I undo a merge file?

button, Merge → Copy to Left, Ctrl+Alt+Left, context menu in File pane within a difference. Undo or pressing Ctrl+Z.

How do you undo a git merge after pushing the changes?

Now, if you have already pushed the merged changes you want to undo to your remote repository, you can right-click on the merge commit and select Revert commit from the context menu.


1 Answers

You can use rebase to do that in one step:

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.

   _D'
  /
 /
A_______C___D
 \     /
  \_B_/

Doc about git rebase --onto, which is more or less your situation: http://git-scm.com/docs/git-rebase


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. Discard the commit F' altogether.

$ 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:

$ git checkout the_branch
$ git merge master

... and fix the conflicts.

like image 147
Gauthier Avatar answered Sep 18 '22 14:09

Gauthier