wired_in
wired_in

Reputation: 2613

Undo a git merge created by a bitbucket pull request

I know there is a lot of information about undoing a merge in git, but I can't seem to find any concensus on how to do this in my specific situation.

Someone essentially merged our develop branch in to our master branch via a pull request in bitbucket. This just happened today, so it's the last thing that was done on the master branch (we don't have to worry about other commits on top of the merge commit).

Note: We host bitbucket ourselves, so we have an older version of bitbucket. There is no revert pull request option.

From what I've read, there is essentially two ways of handling this in git:

  1. git reset --hard *<SHA of commit before the merge>*

    • This will remove the merge commit as if it never happened.
    • Everywhere I read that "it's bad practice to rewrite history" or "never do this on a publicly shared repo" but they never really explain why not to do it. This seems like it will fix the problem, and it won't become a problem 6 months from now when we actually do want to redo this merge from develop to master
    • If this is the best way to do it, and we do it, what happens to the pull request in bitbucket? That pull request still exists in bitbucket, but we are removing the merge commit it created, so will that mess up bitbucket in any way?
  2. git revert -m 1 *<SHA of the merge commit>*

    • This will create a new commit that undoes the changes that were done by the merge
    • This would be fine, except we do intend to merge develop into master at a later date (the next release), and from what I've read, we would have to remember to revert our revert commit before doing this, because otherwise when we merge develop into master, the changes that we revert today won't be included. I really don't want to have this become a problem 6 months from now, when no one remembers this revert.

TL;DR: I'm hesitant on doing git revert because of the issues it could cause 6 months from now when we do want to do this merge again. I'm also hesitant on doing git reset because everyone seems to warn against doing it, and it could cause issues with the pull request on bitbucket.

Upvotes: 1

Views: 5803

Answers (2)

RuSh
RuSh

Reputation: 169

[As I am yet to get enough reputations, I can not put comments on your question, so adding my comments as answer]

The only way I know to revert to old hash of master (without showing merge commit and then reversal of the commit) is to force-push. Refer git force-push for examples and options.

This is a debatable answer, as there are many with opinion against it. But as you are using bitbucket, the force-push can be controlled, i.e. enable it for your operation and disable the force-push for your master.

Note: bitbucket latest plugins like rebase and squash use --force-with-lease.

Upvotes: 0

max630
max630

Reputation: 9248

You can do either. There is really no decisive technical reasons which would dictate you what to do.

  1. in exceptional cases it's ok to update non-forward. Explain to each, ask team who has pulled the erroneous master, help them to recover.

  2. You can forward the development branch to revert commit, then revert the revert, thus returning to its content.

PS for case 2:

For original case

* 73d5415 (HEAD -> master) master3
| * e660100 (development) development3
| * 0356d3a development2
| * 6cefad0 development1
|/  
* 209d967 master2
* dc25505 master1

You merged the development into master, and reverted it.

* 7a4f94a (HEAD -> master) Revert "Merge branch 'development'"
*   75e1e34 Merge branch 'development'
|\  
| * e660100 (development) development3
| * 0356d3a development2
| * 6cefad0 development1
* | 73d5415 master3
|/  
* 209d967 master2
* dc25505 master1

Now to fix it, you shoud do

$ git checkout development
$ git merge --ff-only master
$ git revert 7a4f94a (the "Revert" commit)

Result:

e7b511a (HEAD -> development) Revert "Revert "Merge branch 'development'""
* 7a4f94a (master) Revert "Merge branch 'development'"
*   75e1e34 Merge branch 'development'
|\  
| * e660100 development3
| * 0356d3a development2
| * 6cefad0 development1
* | 73d5415 master3
|/  
* 209d967 master2
* dc25505 master1

e7b511a Contains all your development which used to be not in master and can be merged to master later. There is downside though that all of it is represented as single commit, so if you mean to blame somethig it will require one more call in e660100.

Upvotes: 2

Related Questions