Search code examples
gitvisual-studio-2022

Undo Git Rebase in Visual Studio, changes committed but not pushed


I'm using Visual Studio, not the Git Command line, to perform git operations and I accidentally did the rebase backwards (master onto branch instead of branch onto master, master is further ahead). The changes are committed but not pushed. It's now showing that I have 21 Incoming changes and 19 Outgoing changes. Is there some way in the Visual Studio IDE to undo the rebase at this point? All of the Incoming changes are in the Outgoing changes, except the changes in the branch, since I had the latest code. Do I just go through each of the Outgoing changes and revert them? Will that revert the changes for other users as well and essentially delete them?


Solution

  • tl;dr: (Most likely) all you have to do is delete your local copy of master. If you wish to keep it, delete it and check it out again, or git reset --hard origin/master.

    Disclaimer: the below examples are using the command line, but you could do most of this in the Visual Studio UI as well if you prefer, such as checking out branches, and deleting them. (I'm going to assume you know how to do this.)

    Details:

    If you didn't have any new, personal, commits on master, then you can just delete your local copy. Most of the time you don't even need a local copy of master, since you can (and perhaps should) just use origin/master instead any time you need to use it for something. In Visual Studio, simply use origin/master instead of master for what you normally do. For command line examples:

    # Update all my copies of remote branches:
    git fetch
    
    # Create a new branch
    git switch -c some-new-feature origin/master --no-track
    
    # Update your feature branch
    git switch some-new-feature
    git rebase origin/master
    # Or in a single command even if your branch isn't checked out:
    git rebase origin/master some-new-feature
    

    The main benefit of not having a local copy of master is it's usually out of date, and if you forget to update it you'll be using an old copy of it.

    That being said, if you really want to have a local copy, in your case, you could do a hard reset of it:

    # checkout master
    git switch master
    
    # reset it to the remote version which is what you had before the rebase:
    git reset --hard origin/master
    # OR
    git reset --hard @{u} # this is just shorthand for the remote tracking branch
    
    # OR just delete it and check it out again
    git switch --detach # in case you have master checked out right now
    git branch -D master # delete your local copy
    git switch master # check it out again which will be origin/master
    

    Side Note: in the case where you actually did have personal commits on master that you care about, then use git reflog to find the commit ID that you were on right before the rebase, and then reset it hard to that:

    git switch master
    git reset --hard <commit-id-before-rebase>
    

    From the wording of the question though I don't think this is the case.