Recovery

Recover after a bad rebase

When rebase introduces conflicts, missing commits, or a result you no longer trust, stop rewriting history and recover control with abort, reflog, and rescue branches.

Who This Is For
  • Anyone actively handling a Git mistake
  • Readers who want a conservative rescue habit before trouble happens
Prerequisites
  • Stop mutating the repo further
  • Be ready to inspect `git reflog`, `git status`, and `git log --graph`
Common Risks
  • Running more reset or rebase commands before preserving a checkpoint
  • Changing shared history before assessing blast radius

Data & Performance

Key Quotes

After a rebase, the pre-rebase HEAD is still recorded in the reflog; git reset --hard HEAD@{1} or ORIG_HEAD restores the original branch state.

Citations & Further Reading

  1. Git rebase [Official]
  2. Git reflog [Official]
  3. Git Branching Rebasing [Book]

What you will learn

  • Understand the core purpose of Recover after a bad rebase
  • Master the basic usage and common options of Recover after a bad rebase
  • When rebase introduces conflicts, missing commits, or a result you no longer trust, stop rewriting history and recover control with abort, reflog, and rescue branches.
  • Understand key concepts: The main mistake is usually continuing blindly
  • Know when to use this feature and when to avoid it

Start with a problem

You just ran a Git command and the result wasn't what you expected — maybe you even lost some commits. This has happened before, and you want a reliable set of recovery techniques.

The main mistake is usually continuing blindly

Rebase Recovery StrategyRebase rewrites commit history, producing new-ID commits. Old commits do not disappear immediately — reflog can show the pre-rebase state, and --abort can be used mid-process.
Before rebase (safe state)
main
ABCD
feature
BEF
After rebase (may be problematic)
main
ABCD
feature
DE'F'

When people see conflicts, strange ordering, or “missing” commits after a rebase, they often respond by trying more rebase, reset, and checkout commands in panic.
The safer move is to stop and preserve the last trustworthy state first.

Separate two situations

Situation 1: the rebase is still in progress

Git will usually tell you that you can:

  • git rebase --continue
  • git rebase --skip
  • git rebase --abort

If you no longer trust the intermediate state, --abort is usually the safest option.

Situation 2: the rebase finished, but the result looks wrong

That is when reflog matters most:

git reflog

Find the position from before the rebase and create a rescue branch:

git switch -c rescue/pre-rebase HEAD@{3}

Why commits appear to vanish

Rebase does not “move” the old commit objects. It replays your work on a new base and creates new commits.

That means:

  • commit IDs change
  • parent relationships change
  • old commits may still exist for a while, but your branch no longer points to them

So the problem is often “the name moved,” not “the data was instantly deleted.”

A conservative recovery flow

git status
git log --oneline --graph --decorate -n 30
git reflog
git switch -c rescue/pre-rebase <old-commit>

Then choose one of three paths:

  • go back to the pre-rebase state
  • rescue only a subset of commits
  • restart the rebase more carefully

When git rebase --abort is the right choice

Prefer --abort when:

  • the rebase is still active
  • you no longer know which conflict you are resolving
  • you are unsure whether skip would drop meaningful work
  • this was only local cleanup and not worth gambling on

When to create a rescue branch first

If the rebase already finished and you want to compare “before” and “after,” create a rescue branch first.
Its job is not to fix everything immediately. Its job is to preserve evidence and a known-good checkpoint.

One practical rule

After a bad rebase, the first goal is not “get to push again quickly.”
The first goal is “return to a state I can explain.”

Try it yourself

  1. Practice the recover-after-rebase command in a test repository and observe state changes before and after
  2. Experiment with different options and compare the output differences
  3. Simulate a real scenario where you would need to use this, and walk through the full process

Further reading

Keep going on the same topic: