Data report"State of code review 2024" is now liveRead the full report

Git undo rebase

Greg Foster
Greg Foster
Graphite software engineer


Note

This guide explains this concept in vanilla Git. For Graphite documentation, see our CLI docs.


Rebasing allows you to move branches around and alter commit history by re-writing commits. This can be useful for cleaning up a messy history or updating a topic branch with the main branch.

However, a rebase can sometimes introduce bugs or issues you want to undo. Or perhaps you rebased the wrong branch by accident. Let's explore some options for undoing the effects of a rebase in Git.

The easiest way to undo a rebase is to find the commit SHA of the branch tip before the rebase occurs. We can use git reflog to find this:

Terminal
$ git reflog
f0a0f6f HEAD@{245}: rebase (finish): returning to refs/heads/main
f0a0f6f HEAD@{246}: rebase (pick): Cleaned up the folder a little
0e911ec HEAD@{247}: rebase (start): checkout refs/remotes/origin/main

Here, we see f0a0f6f was the tip of origin/main right before we started the rebase. We can reset back to this state with:

Terminal
$ git reset --hard f0a0f6f
HEAD is now at f0a0f6f Cleaned up the folder a little

The branch now looks as if we never performed the rebase.

Resetting works well for local experimentation. However, git reset --hard re-writes history, which can cause issues if working on a shared branch that's been pushed to GitHub. The git revert approach mentioned below will be safer for published branches since it preserves history.

Git also saves the starting point of a rebase in ORIG_HEAD. So, an alternative way to undo is:

Terminal
$ git reset --hard ORIG_HEAD

One caveat is that ORIG_HEAD will get overwritten by subsequent git commands like merge, rebase, etc. So, if other commands have run since, the reflog method may be better.

If previous commits are no longer available, we can rebase back onto the original base again. Suppose the feature was branched from main at commit abcd123:

Terminal
$ git rebase --onto abcd123 main feature

This replays the feature commits on top of the commit it was originally branched from, effectively undoing the rebase.

To undo a rebase while preserving history, we can revert the new commits that were brought in:

Terminal
$ git log main..feature
$ git revert <commit 1> <commit 2>

This will introduce new commits that cancel out the changes from the rebase.

Choose the appropriate strategy based on whether the branch has been shared publicly or exists only locally. Resetting with git reset --hard is ideal for throwaway branches.

But if a branch has been pushed online where others may depend on it, use git revert to cleanly undo changes without rewriting history. The key is being able to identify the commit(s) prior to the rebase through git reflog, ORIG_HEAD, or other means.

Stay unblocked. Ship faster.
Experience the new developer workflow - create, review, and merge code continuously. Get started with one command.
Learn more

Give your PR workflow
an upgrade today

Stack easier | Ship smaller | Review quicker

Or install our CLI.
Product Screenshot 1
Product Screenshot 2