Recovery
Recovering with reflog
Use reflog to locate previous references and recover from reset, rebase, or lost branch states.
- Anyone actively handling a Git mistake
- Readers who want a conservative rescue habit before trouble happens
- Stop mutating the repo further
- Be ready to inspect `git reflog`, `git status`, and `git log --graph`
- Running more reset or rebase commands before preserving a checkpoint
- Changing shared history before assessing blast radius
git reflog is often the most practical recovery tool in everyday Git accidents. After a bad reset, rebase, amend, or pull, what you usually lose first is not the commit object itself but the name and reference that used to point to it.
Reflog does not magically undo everything for you. It helps you answer a more important question first: where did this branch or HEAD point before things went sideways? Once you know that, the recovery strategy becomes much easier to choose safely.
When reflog is the right first stop
- after a
reset --hardyou regret - after a rebase that rewrote history in the wrong way
- after a
pullthat changed the branch differently than expected - after deleting a branch and suspecting the commits still exist
- after
commit --amendor interactive rebase when you want the previous state back
The real value is that you do not need to know the final recovery plan yet. You only need to relocate the trustworthy old state.
A conservative recovery flow
1. Inspect reflog before trying more mutations
git reflog --date=local
Look for entries that correspond to the operation right before the mistake. Useful clues often include:
reset: moving to ...rebase (start)/rebase (finish)checkout: moving from ... to ...commit (amend): ...
2. Create a rescue branch before resetting anything
git switch -c rescue/recover HEAD@{1}
If HEAD@{1} is not the correct entry, use the SHA or another reflog position instead.
The goal here is not to finish the recovery immediately. It is to pin the old state somewhere safe so later experiments do not erase your best recovery target.
3. Choose the real restoration path afterward
- want the current branch to return to that state:
git reset --hard <target> - want to keep today’s state and recover in parallel: continue on the
rescue/*branch - want only some commits back:
git cherry-pick <sha> - want to compare both sides first:
git log --oneline --graph --decorate --all
Why “branch first, reset later” is safer
Many people know reflog is useful, but still jump straight from “I found the old SHA” to “I will reset immediately.” The problem is that recovery commands are also reference-moving commands. If you guess wrong once, you can make the situation harder to reason about.
A safer rhythm is:
- run
git reflog - create
rescue/... - inspect content and history on that rescue branch
- only then decide whether the original branch should move
This costs a little more time, but incident response is usually better when it is calm and reversible.
Three common recovery situations
Recover after reset
Your job is to find the branch tip from before the reset, pin it on a rescue branch, and only then decide whether the original branch should be moved back.
Recover after rebase
Do not focus first on which SHAs changed. Focus on where the branch pointed before the rebase started. Reflog usually makes that visible quickly.
Recover after pull
First understand what the pull actually did:
- fast-forward
- merge
- or rebase
Then use reflog to locate the pre-pull position. Do not hard-reset blindly before you know what changed.
Reflog is powerful, but it has limits
- reflog is local, not a shared cross-machine audit log
- entries are not kept forever
- aggressive cleanup and time can shrink the recovery window
- success still depends on whether the old objects remain available
That is why the best habit is to create a rescue branch as soon as you find a meaningful old position.
Reflog is a recovery window, not a permanent backup strategy. When you find a useful old position, capture it early. A rescue branch is often the difference between a controlled recovery and a second accident during the first one.
Common mistakes
Resetting immediately after finding an old SHA
You may be right, but it is still the riskier sequence. Branch first if you want a reversible path.
Thinking reflog matters only after reset
Checkout, merge, rebase, amend, and pull can all leave useful reflog entries.
Assuming deleted branch means deleted commits
Sometimes only the name disappeared. The objects may still exist and be recoverable.
Create a tiny repository, make a reversible mistake, and use reflog to recover it. This is one of the highest-value Git drills you can run.
mkdir reflog-lab && cd reflog-lab git init echo one > notes.txt git add notes.txt git commit -m "init" echo two >> notes.txt git commit -am "second" echo three >> notes.txt git commit -am "third"Steps
- Run `git reset --hard HEAD~1`
- Inspect `git reflog --date=local` and find the pre-reset entry
- Create `git switch -c rescue/recover HEAD@{1}`
- Compare both branches with `git log --oneline --graph --decorate --all`
- Decide whether the original branch should move back or whether rescue work should continue separately
- The old commit does not vanish immediately
- A rescue branch safely captures the old position
- The current branch and rescue branch become easier to reason about
- Recovery becomes a choice, not a panic reaction
- Running another hard reset before creating a rescue branch
- Forgetting which reflog entry was the pre-incident state
- Treating `HEAD@{1}` as always correct without inspecting the reflog context
The habit worth remembering
When Git history looks wrong, start with this:
git reflog- create a rescue branch
- choose reset, cherry-pick, merge, or manual reconstruction only after the old position is safe