Advertisement
Advertisement


Undoing a git rebase


Question

Does anybody know how to easily undo a git rebase?

The only way that comes to mind is to go at it manually:

  • git checkout the commit parent to both of the branches
  • then create a temp branch from there
  • cherry-pick all commits by hand
  • replace the branch in which I rebased by the manually-created branch

In my current situation this is gonna work because I can easily spot commits from both branches (one was my stuff, the other was my colleague's stuff).

However my approach strikes me as suboptimal and error-prone (let's say I had just rebased with 2 of my own branches).

Any ideas?

Clarification: I'm talking about a rebase during which a bunch of commits were replayed. Not only one.

2020/06/12
1
3267
6/12/2020 12:08:08 PM

Accepted Answer

The easiest way would be to find the head commit of the branch as it was immediately before the rebase started in the reflog...

git reflog

and to reset the current branch to it (with the usual caveats about being absolutely sure before reseting with the --hard option).

Suppose the old commit was [email protected]{5} in the ref log:

git reset --hard [email protected]{5}

In Windows, you may need to quote the reference:

git reset --hard "[email protected]{5}"

You can check the history of the candidate old head by just doing a git log [email protected]{5} (Windows: git log "[email protected]{5}").

If you've not disabled per branch reflogs you should be able to simply do git reflog [email protected]{1} as a rebase detaches the branch head before reattaching to the final head. I would double check this, though as I haven't verified this recently.

Per default, all reflogs are activated for non-bare repositories:

[core]
    logAllRefUpdates = true
2016/10/20
4466
10/20/2016 3:32:48 AM

Actually, rebase saves your starting point to ORIG_HEAD so this is usually as simple as:

git reset --hard ORIG_HEAD

However, the reset, rebase and merge all save your original HEAD pointer into ORIG_HEAD so, if you've done any of those commands since the rebase you're trying to undo then you'll have to use the reflog.

2009/03/28

Charles's answer works, but you may want to do this:

git rebase --abort

to clean up after the reset.

Otherwise, you may get the message “Interactive rebase already started”.

2017/01/10

Resetting the branch to the dangling commit object of its old tip is of course the best solution, because it restores the previous state without expending any effort. But if you happen to have lost those commits (f.ex. because you garbage-collected your repository in the meantime, or this is a fresh clone), you can always rebase the branch again. The key to this is the --onto switch.

Let’s say you had a topic branch imaginatively called topic, that you branched off master when the tip of master was the 0deadbeef commit. At some point while on the topic branch, you did git rebase master. Now you want to undo this. Here’s how:

git rebase --onto 0deadbeef master topic

This will take all commits on topic that aren’t on master and replay them on top of 0deadbeef.

With --onto, you can rearrange your history into pretty much any shape whatsoever.

Have fun. :-)

2008/09/26

In case you had pushed your branch to remote repository (usually it's origin) and then you've done a succesfull rebase (without merge) (git rebase --abort gives "No rebase in progress") you can easily reset branch using command:

git reset --hard origin/{branchName}

Example:

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is ahead of 'origin/{branchName}' by 135 commits.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean

$ ~/work/projects/{ProjectName} $ git reset --hard origin/{branchName}
HEAD is now at 6df5719 "Commit message".

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is up-to-date with 'origin/{branchName}.

nothing to commit, working directory clean
2016/02/05

I actually put a backup tag on the branch before I do any nontrivial operation (most rebases are trivial, but I'd do that if it looks anywhere complex).

Then, restoring is as easy as git reset --hard BACKUP.

2013/05/24

Source: https://stackoverflow.com/questions/134882
Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Email: [email protected]