Undoing a git rebase

2018-12-31 05:05发布

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.

15条回答
伤终究还是伤i
2楼-- · 2018-12-31 05:45

For multiple commits, remember that any commit references all the history leading up to that commit. So in Charles' answer, read "the old commit" as "the newest of the old commits". If you reset to that commit, then all the history leading up to that commit will reappear. This should do what you want.

查看更多
路过你的时光
3楼-- · 2018-12-31 05:46

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.

查看更多
后来的你喜欢了谁
4楼-- · 2018-12-31 05:48

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”.

查看更多
唯独是你
5楼-- · 2018-12-31 05:53

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
查看更多
长期被迫恋爱
6楼-- · 2018-12-31 05:54

Following the solution of @Allan and @Zearin, I wish I could simply do a comment though but I don't enough reputation, so I have used the following command:

Instead of doing git rebase -i --abort (note the -i) I had to simply do git rebase --abort (without the -i).

Using both -i and --abort at the same time causes Git to show me a list of usage/options.

So my previous and current branch status with this solution is:

matbhz@myPc /my/project/environment (branch-123|REBASE-i)
$ git rebase --abort

matbhz@myPc /my/project/environment (branch-123)
$
查看更多
永恒的永恒
7楼-- · 2018-12-31 05:58

Using reflog didn't work for me.

What worked for me was similar to as described here. Open the file in .git/logs/refs named after the branch that was rebased and find the line that contains "rebase finsihed", something like:

5fce6b51 88552c8f Kris Leech <me@example.com> 1329744625 +0000  rebase finished: refs/heads/integrate onto 9e460878

Checkout the second commit listed on the line.

git checkout 88552c8f

Once confirmed this contained my lost changes I branched and let out a sigh of relief.

git log
git checkout -b lost_changes
查看更多
登录 后发表回答