Undo a fast-forward merge

Git

Git Problem Overview


I've made some changes to my git repo that I wish to undo.

My git repo looked like this:

A-B----		master
   \   /
    C-D		* develop

I was on the develop branch, forgot that it differed from the master branch, made a change on develop, merged it into master, and then pushed to my remote (called publish).

Because there were no changes on master since B (common ancestor), git did a fast-forward merge.

Now, my repo looks like this:

A-B-C-D   master, develop, remotes/publish/master, remotes/publish/develop.

I wanted to revert the last merge, restoring master to B.

From what I read in https://stackoverflow.com/questions/927358/undo-last-git-commit, I used git reset sha-of-B to restore my master branch to revision B.

Questions:

  • How do I restore develop to revision D?
  • How do I then push these changes back to remote/publish?

Git Solutions


Solution 1 - Git

If you reset the branch master, it won't touch develop branch. In order to reput all in order, you should do:

git checkout master
git reset --hard sha-of-B
git checkout develop
git reset --hard sha-of-D
git checkout master
git merge develop --no-ff

Solution 2 - Git

  • imagine you are still on master where you merged and pushed
  • git reset --hard @{1}
    • this resets branch “master” to where it was one step back on your computer (i.e. at “B”)
  • for develop do nothing, because it should still be at “D”
  • git push publish develop
    • this pushes branch “develop” in the usual way
  • git push publish master --force-with-lease
    • pushes branch “master” backwards, with the permission gained via --force-with-lease in a safe way
    • the use of --force might silently overwrite work from others, so I never use that
  • or both push operations together with this surprising syntax:
    • git push publish develop --force-with-lease=master

Solution 3 - Git

If seems that you were checked out to develop when you ran git reset, and this is what messed you up.

You can fix develop as follows:

git checkout develop
git merge --ff-only D

Now, you can restore master back to B:

git checkout master
git reset --hard B

Get back to develop and push it:

git checkout develop
git push develop

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFabian TampView Question on Stackoverflow
Solution 1 - GitSimon BoudriasView Answer on Stackoverflow
Solution 2 - GitRobert SiemerView Answer on Stackoverflow
Solution 3 - GitmvpView Answer on Stackoverflow