87

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 How to undo last commit(s) in Git?, 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?
Community
  • 1
  • 1
Fabian Tamp
  • 4,416
  • 2
  • 26
  • 42
  • 1
    Blog post summarising and going in to a bit more detail as to what I did, should've done and how I fixed this: http://www.capnfabs.net/software/git-undoing-a-fast-forward-merge-when-you-shouldve-just-used-a-new-branch/ – Fabian Tamp Jan 13 '13 at 22:48
  • 1
    @SnowCrash updated link: http://capnfabs.net/blog/2013/01/14/git-undoing-a-fast-forward-merge/ – Fabian Tamp Jul 11 '15 at 12:50
  • For sole developers this is probably all good, but for those collaborating, wouldn't it make more sense to use `revert` rather than `reset`? – Snowcrash Jul 13 '15 at 19:16
  • 1
    @Snowcrash: `git revert -m 1 hashValue` would fail with message that hashValue is not an merge. Because it is fast forward merge. – Tihomir May 12 '20 at 06:10

3 Answers3

105

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
Simon Boudrias
  • 42,953
  • 16
  • 99
  • 134
35
  • 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
Robert Siemer
  • 32,405
  • 11
  • 84
  • 94
  • 7
    The "git reset --hard @{1}" worked perfect for my situation. I --no-ff a merge and it had 100+ commits and didn't wanna have to to do a soft reset for each one. Thanks! +1 – Brad Bird Aug 22 '16 at 23:15
  • I accidently did a `git checkout develop && git merge -` instead of a `git checkout develop && git merge --no-ff -` (the - denotes the last branch). The above answer worked very well for me, as I didn't do anything in between and was still on develop: `git reset --hard @{1} && git merge --no-ff feature/my-feature-branch` – Thomas Praxl Aug 31 '17 at 13:53
  • As a usability/confidence tip for this: It might help to `git checkout @{1}` and make sure the current branch and history looks like you want it to, before making the big change to reset things at that commit. – Unixmonkey May 25 '19 at 16:43
  • What does "publish" do in `git push publish`? I don't see that word in the git-push docs or by Googling "git publish". – Noumenon Dec 03 '19 at 17:54
  • 2
    @Noumenon That is the name of the repository as established in the question. In the `git push` man page referred to as ``. – Robert Siemer Dec 04 '19 at 16:54
0

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
mvp
  • 111,019
  • 13
  • 122
  • 148
  • Thanks for your answer! I was definitely on the `master` branch, I was just reading the `gitk` gui wrong. I'll edit my question accordingly. – Fabian Tamp Jan 13 '13 at 21:57