A key feature of Git is the ability to rebase commits onto another branch to ensure a streamlined, linear commit history and keep the repository organized. However, there may be situations where you need to undo the effects of a `git rebase` operation. This may be because you have accidentally performed the rebase on the wrong branch, the rebase has introduced bugs or issues, or the changes introduced are not desirable or are no longer necessary.
The short answer
The easiest way to undo a rebase is to find the head of the commit of the branch as it was immediately before the rebase and use the git reset command to rewind the commit history to that specific commit. This commit can be found using the git reflog command, which shows the history of the HEAD pointers.
For example, if the commit before the rebase was HEAD@{2} in the reflog, you can use the following command:
$ git reset --hard HEAD@{2}
Run in Warp
This command allows you to reset the branch to the state it was before the rebase, because a rebased branch detaches the original branch head, before reattaching it to the final head.
Easily retrieve this command using Warp’s AI Command Search
If you’re using Warp as your terminal, you can easily retrieve this command using the Warp AI Command Search feature:
Entering git reset hard in the AI Command Search will prompt a git command that can then quickly be inserted into your shell by doing CMD+ENTER.
Using the ORIG_HEAD pointer
Alternatively, when performing a rebase, git saves your starting point before the rebase as ORIG_HEAD.
This means that you can also use the following command:
$ git reset --hard ORIG_HEAD
Run in Warp
It must be noted however that the git reset, git rebase, and git merge commands all save the original HEAD pointer into ORIG_HEAD. This means that if you have used any of these commands following the rebase, you will instead have to use the reflog to identify how to reset the branch.
Using the remote repository
If the branch you are trying the rollback has been pushed to the remote repository before the rebase operation, you can use it as a backup to reset the branch using the following command:
$ git reset --hard origin <branch_name>
Run in Warp
Where <branch_name> is the reference you use in the remote repository. However, note that this can cause conflicts if your local branch contains commits that haven't been pushed to the remote repository.
Undoing a rebase with git rebase
In some cases the previous state of the branch before the rebase may be no longer available. An alternative is to rebase the branch again back onto the original base of the branch. This can be done using the --onto flag if you know the commit where the branch originated from.
For example, a branch named feature was originally branched off main when the tip of main was xcommit. A rebase was then performed back onto the main branch using git rebase main.
To undo this rebase, you can use the following command:
$ git rebase --onto xcommit master feature
Run in Warp
This will take all of the commits on the feature branch that aren’t on the main branch and move them on top of xcommit.
Undoing a rebase with git revert
A more complicated but history preserving way of undoing a rebase is to use the git revert command that will revert the new commits (i.e. create new opposing commits) introduced from the branch you rebased onto.
For example, a feature branch was originally branched off main at xcommit. A rebase was then performed back onto main at ycommit. In this case, you can use the git log command to find the commits between xcommit and ycommit, and undo them one by one using the git revert command as follows:
$ git revert <xcommit+1> <xcommit+2>…<ycommit>
Run in Warp
Alternatively, you can also take advantage of the commit range feature of git revert by specifying the commit after the original and the latest commit on the main branch:
$ git revert <xcommit+1>..<ycommit>
Run in Warp
Which will create revert commits from <xcommit+1> up until <ycommit>.
Undoing local vs remote rebase
When you haven’t pushed the changes to a remote repository then the process of undoing a rebase becomes simpler. This is because you don’t have to worry about the effects on other developers or the impact on the history of the repository. The simplest solution would be to use any of the git reset or git rebase options presented above.
If you have pushed the rebased branch up to the remote repository, other developers may already be using the rebased branch. In such cases, changing the branch history can lead to conflicts and confusion within the team. In this case, the best solution is to use the git revert solution presented above, which preserves the branch's history and creates new commits that other developers can then use.
Undo a squashed rebase
A common rebase operation is a squash rebase where all, or some of the commits in the branch are squashed together into a single commit before they are rebased onto a new branch. This discards the original commits and creates a new consolidated single commit. The only way to resolve this and to restore the original commit structure is to use the reset option, which will restore the branch to its original condition.
Written by
Philip Wilkinson
Software Engineer, Amazon
Filed Under
Related Articles
Undo A Git Pull
How to effectively remove the commits introduced by a pull in Git using git-reset and preserve your local changes using git-stash. Also, how to cancel an unmerged pull request on GitHub.
Undo a Git Merge
How to rollback the changes introduced by a merge in Git by adding new opposite commits using git-revert and effectively removing commits using git-reset.
Prompt Show Git Branch In Prompt
Enhance your terminal with a custom Git prompt. Learn different ways to integrate this contextual info, from custom shell functions to Warp context chips and toolkits like Starship and P10K.
How To Remove Secrets From The Git History Remove Secrets From The Git History
Learn how to remove secrets from the Git history using the BFG and git-filter-repo command-line tools.
Adding a Submodule in Git
This post will show you how to simply add a submodule to a local repository, clone a repository with a submodule, and work within a repository that has a submodule.
Undo a git push
This post will show you had to simply undo a git push three different ways.
Undo Git Add
Learn how to effectively use 'git add' to stage files in Git for committing, and discover two powerful methods to undo accidental stagings.
Git Push Origin
A breakdown of git push origin
Create Folder In GitHub Repository
Learn how to create and push one or more empty directories in a Git repository using `.placeholder` and `README.md` files using both the CLI and the GitHub interface.
Git Push Tags
This post will show you how to push a single tag, multiple tags, all tags, and tags with commits.
Undoing Git Commits
Explore ways to undo a commit, including git reset, git checkout, and git revert with git while preserving commit history.
Delete Local Git Branch
Learn how to delete local branches from your git repository, including ones with unmerged changes, as well as local remote-tracking branches.