🔀 The Commit That Vanished From an Interactive Rebase Without a Trace
An interactive rebase lets you reorder, squash, reword, and drop commits by editing a simple todo list before Git replays them one by one – which is exactly what makes it easy to delete the wrong line, or change pick to drop on a commit you actually meant to keep. Once the rebase finishes, that commit is gone from the branch’s history as if it never happened, with no warning and no undo prompt, even though the commit object itself is still sitting intact in Git’s object database for a while yet.
🔎 The Problem
$ git rebase -i HEAD~5
# In the editor, you meant to drop a different line but accidentally
# changed "pick a1b2c3d Add refund calculation" to "drop a1b2c3d ..."
$ git log --oneline
# a1b2c3d (the refund calculation commit) is simply gone - no error,
# no warning, the rebase completed successfully.
# The commit still exists; reflog remembers where HEAD pointed before
# the rebase ran:
$ git reflog
f9e8d7c HEAD@{0}: rebase (finish): returning to refs/heads/feature
...
c4d5e6f HEAD@{5}: rebase (start): checkout HEAD~5
a9b8c7d HEAD@{6}: commit: Add refund calculation <- the commit
right before
the rebase started
✅ Fix: Use the Reflog to Find and Cherry-Pick the Dropped Commit Back
- Run git reflog immediately – it records every position HEAD has pointed to, including right before the interactive rebase started, so you can find the commit’s hash even though it no longer appears in git log.
- Once you have the dropped commit’s hash, run git cherry-pick with that hash on your current branch to reapply it cleanly, rather than trying to redo the entire rebase from scratch.
- Act quickly: reflog entries are not permanent and eventually expire (90 days by default for reachable commits, much sooner for ones Git considers already unreachable), after which the commit becomes genuinely unrecoverable through normal means.
⚠️ Why This Is Easy to Miss
- The rebase itself reports success with no errors, and the resulting history looks clean and intentional – there’s no diff, no warning dialog, nothing that distinguishes an accidental drop from a deliberate one.
- The missing commit is often only noticed much later, when a feature it implemented turns out to be missing in testing or production, by which point it’s easy to assume the work was never committed in the first place rather than lost in a rebase.
Git doesn’t forget a commit the moment you drop it – it just stops showing it to you, and the reflog is where it keeps the receipt.
