Can I delete remote master branch and push a prior local master to origin to undo an incorrect merge to master?
Asked by Tim Ahrens:

We accidently merged develop to master and pushed master to origin. Now I wish to restore master to it's prior state (before the merge of develop to master). In SourceTree, I right-clicked the prior version of master and selected 'Reset current branch to this commit', and selected 'Hard' and my local master is good. Can I then, just right-click the Remotes/origin/master version in the left navigation bar and select 'Delete origin/master', and then push that result? I am on a small team, so controlling what the rest of the team does, it easy.

Followup:

We are using Bitbucket Cloud, and we normally have our setting set to disallow deleting develop and master. I temporarily turned off the restriction on deleting master, in order to delete it, but it still prevented the delete saying: 'remote: permission denied to delete branch master\[K'

Also tried to do the reverse commit but SourceTree would not do that either Saying: 'git -c diff.mnemonicprefix=false -c core.quotepath=false revert --no-edit 3fa61aa...4f

error: Commit 3fa61aa...4f is a merge but no -m option was given.  
fatal: revert failed'

Solution:

I was finally able to accomplish my desired task by turning off the 'Prevent history re-writes (rebase) on these branches' in Bitbucket Settings/Branch management, and then used Git command line:

git push -f

Then I added master branch back to 'Prevent history re-writes (rebase) on these branches' section, to ensure no one does this kind of thing by accident.


Answers:
author: Tim Crall
body: You should be able to just do a force push on the master branch to restore it to what you have locally, assuming your remote allows force-pushes on master (which is generally a bad idea, but if you know what you're doing...)

I'm not seeing a force push option in SourceTree off hand but you can go to the command line and do

```
git push -f
```

If you do this (and also if you went with your plan), anyone who has a local copy of the old wrong master branch is going to have trouble. Actually, in this case, they won't so much have trouble as they will be likely to re-push the bad commits if they're not careful. They should either reset their local master branch the same way you did or delete and re-pull the master branch.

The more "correct" way to do this in a larger environment where other developers having the wrong commits was a bigger issue would be to do a revert rather than a reset, adding a new commit that undoes the merge.

In order to use git revert with a merge commit, you need to use the -m flag to specify which of the commit's parents to use as a baseline.

A merge commit, to Git, is just a commit with two parents. Typically one of them represents the branch you "merged into" (the master branch) and the other represents the branch that you merged (develop branch). But to Git, they are just parent 1 and parent 2.

The "merged into" branch represents your baseline while the "merged" branch represents the changes that you want to revert. It seems like the "merged into" branch is usually P1, but I wouldn't count on this - examine your Git history to determine for sure. If you look at the details of a commit in SourceTree or using the command

```
git show --pretty=%P <commit>
```

the first parent listed will always be P1.

Once you've determined which parent is your baseline, the command is

```
git revert -m <baseline> <commit>
```

where baseline is the number 1 or 2 (or, rarely, another number for a commit with more than two parents)

Using revert will not create as pretty a history as fixing it locally with reset and doing a force push, but it is less likely to result in the error being re-pushed by someone with a local copy of the wrong version of the branch.

comments: author: Tim Crall
body: If for some reason your remote allows you to delete master but not to do a force push on it, yes, deleting it and then pushing it seems like it would also work. A typical setup would be likely to prohibit both of those actions - are you using Bitbucket Cloud, Bitbucket Server / Stash, or another remote?