Undo a Git merge that hasn't been pushed yet

2018-12-31 03:48发布

Within my master branch, I did a git merge some-other-branch locally, but never pushed the changes to origin master. I didn't mean to merge, so I'd like to undo it. When doing a git status after my merge, I was getting this message:

# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.

Based upon some instructions I found, I tried running

git revert HEAD -m 1

but now I'm getting this message with git status:

# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.

I don't want my branch to be ahead by any number of commits. How do I get back to that point?

27条回答
谁念西风独自凉
2楼-- · 2018-12-31 04:02

Okay, the answers other people here gave me were close, but it didn't work. Here's what I did.

Doing this...

git reset --hard HEAD^
git status

...gave me the following status.

# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.

I then had to type in the same git reset command several more times. Each time I did that, the message changed by one as you can see below.

> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 2 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 1 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.

At this point, I saw the status message changed, so I tried doing a git pull, and that seemed to work:

> git pull
Updating 2df6af4..12bbd2f
Fast forward
 app/views/truncated |    9 ++++++---
 app/views/truncated |   13 +++++++++++++
 app/views/truncated |    2 +-
 3 files changed, 20 insertions(+), 4 deletions(-)
> git status
# On branch master

So long story short, my commands came down to this:

git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git pull
查看更多
何处买醉
3楼-- · 2018-12-31 04:02
  1. First, make sure that you've committed everything.

  2. Then reset your repository to the previous working state:

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
    

    or using --hard (this will remove all local, not committed changes!):

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
    

    Use the hash which was there before your wrongly merged commit.

  3. Check which commits you'd like to re-commit on the top of the previous correct version by:

    $ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    ...
    
    commit 16b373a96b0a353f7454b141f7aa6f548c979d0a
    
    ...
    
  4. Apply your right commits on the top of the right version of your repository by:

    • By using cherry-pick (the changes introduced by some existing commits)

          git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
      
    • Or by cherry-picking the range of commits by:

      • First checking the right changes before merging them:

        git diff 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        
      • First checking the right changes before merging them:

        git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        

        where this is the range of the correct commits which you've committed (excluding wrongly committed merge).

查看更多
十年一品温如言
4楼-- · 2018-12-31 04:03

Lately, I've been using git reflog to help with this. This mostly only works if the merge JUST happened, and it was on your machine.

git reflog might return something like:

fbb0c0f HEAD@{0}: commit (merge): Merge branch 'master' into my-branch
43b6032 HEAD@{1}: checkout: moving from master to my-branch
e3753a7 HEAD@{2}: rebase finished: returning to refs/heads/master
e3753a7 HEAD@{3}: pull --rebase: checkout e3753a71d92b032034dcb299d2df2edc09b5830e
b41ea52 HEAD@{4}: reset: moving to HEAD^
8400a0f HEAD@{5}: rebase: aborting

The first line indicates that a merge occurred. The 2nd line is the time before my merge. I simply git reset --hard 43b6032 to force this branch to track from before the merge, and carry-on.

查看更多
有味是清欢
5楼-- · 2018-12-31 04:03

Got to this question also looking to revert to match origin (ie, NO commits ahead of origin). Researching further, found there's a reset command for exactly that:

git reset --hard @{u}

Note: @{u} is shorthand for origin/master. (And, of course, you need that remote repository for this to work.)

查看更多
有味是清欢
6楼-- · 2018-12-31 04:03

You can use only two commands to revert a merge or restart by a specific commit:

  1. git reset --hard commitHash (you should use the commit that you want to restart, eg. 44a587491e32eafa1638aca7738)
  2. git push origin HEAD --force (Sending the new local master branch to origin/master)

Good luck and go ahead!

查看更多
心情的温度
7楼-- · 2018-12-31 04:04

If you committed the merge:

git reset HEAD~1
# Make sure what you are reverting is in fact the merge files
git add .
git reset --hard
查看更多
登录 后发表回答