Here’s the scenario:
I had a git repo that looks like this:
A-B---- master \ / C-D *develop
I was on the
develop branch. Here’s the foolish thing that I did:
- I forgot that
developdiffered from the
- Made a change on
develop, committed it, and merged it into
- Pushed the change to my remote (called
There were no changes after
B on the
master branch, and as such, when I
merged, git did a fast-forward. My repo now looked like this:
A-B-C-D master, develop, remotes/publish/master, remotes/publish/develop.
I wanted to keep
D, but revert
B, and then merge the changes made at
What I Should’ve Done to Start With
What I should’ve done was:
git checkout master #change to `master` branch git checkout -b hotfix #make a new branch called `hotfix` from `master` #make file changes git commit #commit the `hotfix` git checkout master #switch back to `master` git merge hotfix #pull in the hotfix changes git checkout develop #switch to `develop` git merge hotfix #pull in the hotfix changes git push publish #push everything to my remote.
Resulting in a diagram that looks like this:
D-- hotfix / \ A-B---- E master \ | C---F *develop
Fixing the Mistake
Turns out the solution wasn’t really that hard, but git can be really scary if you’re not sure what you’re doing. The
develop branch is already in the right spot, so we just need to:
# Make sure we're on the `master` branch git checkout master # Move `master` back to revision `B`, deleting all other changes in the working # directory. git reset --hard sha-of-B # Because we've reverted some changes, we need to force the remote to accept the # reversion. git push publish --force
That reverts the
master branch back before the merge. To then pull in the changes made in the hotfix:
git cherry-pick sha-of-D #pull in only the changes made in revision D. git push publish
And we’re done!
Thanks to Simon Boudrias for his help on this one. See the StackOverflow question here.