Contaminated Remote master branch or Anti-Cherry-Pick
Question
I have a situation where the remote repository has some "bad" commits. e.g.
... o ---- C ---- A ---- B origin/master
Where A is bad (but B is good) I want the remote to become...
... o ---- C ---- B origin/master
\
A origin/dev
It is not obvious to me how to do this.
In the case where a rebase is inappropriate a different result is needed.
... o ---- C ---- A ---- B ---- ~A origin/master
\
- origin/dev
This results in a dev branch containing the A commit and the master not containing the A commit. The revised question is: How to do an anti-cherry-pick? So rather than generating a patch which changes the repository from state C to A apply a patch which changes B to A.
Solution
Pull so that you have the same repository locally.
Use git rebase --interactive
(see this rundown if you are unfamiliar with interactive rebase) to reorder the A and B commits, so that you now have
... o ---- o ---- B ---- A master
Checkout a new branch dev from that spot, so you get
... o ---- o ---- B ---- A master, dev
Switch to the master branch, do a git reset --hard HEAD^
to rewind that branch one commit. You now have
... o ---- o ---- B master
\
A dev
Now git push --force --all
and you should be golden. (You need --force
because you are rewriting history in the remote repository, which is dangerous and not recommended if other developers have already pulled from it.)