git reflog: Recover Lost Commits, Deleted Branches and Bad Rebases

Lost commits after a reset, deleted a branch or broke a rebase? Git almost never forgets. In this lesson you will read the reflog and use step-by-step recovery recipes to get your work back.

Advertisement

📖 What You’ll Learn: what the reflog is and how long it keeps entries, reading reflog entries and HEAD@{n} references, recovering from reset –hard, deleted branches, bad rebases and amends, recovering dropped stashes, and safe habits before risky operations.


🛟 What Is the Reflog?

The reflog (reference log) is Git’s private diary of where HEAD and your branch tips have been. Every commit, checkout, reset, rebase, merge and amend adds an entry. Even when a commit disappears from git log (after a reset, a bad rebase or a deleted branch), it is usually still listed in the reflog, so you can get it back.

Key facts:

  • The reflog is local to your repository; it is not pushed or shared.
  • Entries are kept for a while: by default about 90 days for reachable entries and 30 days for unreachable ones, after which git gc may remove them.
  • It only knows about commits. Changes that were never committed (for example discarded with git restore) cannot be recovered with it.

📜 Read the Reflog

git reflog
8b1d4e2 (HEAD -> main) HEAD@{0}: reset: moving to HEAD~2
f6a7b8c HEAD@{1}: commit: Add API tests for orders
e5f6a7b HEAD@{2}: commit: Add checkout tests
8b1d4e2 HEAD@{3}: checkout: moving from feature/login to main
PartMeaning
8b1d4e2The commit HEAD pointed to
HEAD@{2}“Where HEAD was two moves ago”
reset: moving to HEAD~2The action that caused the move

More views:

git reflog show feature/login         # history of one branch's tip
git reflog --date=iso                 # with timestamps
git log -g --oneline                  # reflog in git log format
git show HEAD@{2}                     # inspect an entry
git diff HEAD@{1} HEAD                # what changed since the previous position

You can also use time: git show main@{yesterday} or HEAD@{2.hours.ago}.


🚑 Recovery Recipes

1. Undo an accidental git reset –hard

git reflog
# f6a7b8c HEAD@{1}: commit: Add API tests for orders   ← the commit you lost
git reset --hard f6a7b8c                 # or: git reset --hard HEAD@{1}

2. Recover a deleted branch

git branch -D feature/api-tests
# Deleted branch feature/api-tests (was a9b8c7d).   ← Git prints the branch's last commit
git switch -c feature/api-tests a9b8c7d             # recreate the branch at that commit

# Lost that message? Search the reflog for the branch name:
git reflog | grep "feature/api-tests"
# 1f2e3d4 HEAD@{4}: checkout: moving from feature/api-tests to main
# a9b8c7d HEAD@{5}: commit: Add API tests for orders   ← one entry older = last commit on the branch

On Windows PowerShell use git reflog | Select-String "feature/api-tests".

3. Undo a rebase that went wrong

git reflog
# 1a2b3c4 HEAD@{6}: rebase (start): checkout main
# 7d8e9f0 HEAD@{7}: commit: Add cart tests       ← the state before the rebase
git reset --hard HEAD@{7}

Tip: the entry just before “rebase (start)” is the branch as it was. Git also stores it in ORIG_HEAD right after a rebase or reset: git reset --hard ORIG_HEAD.

4. Get back an amended commit’s previous version

git reflog
# 3c4d5e6 HEAD@{0}: commit (amend): Add login tests
# 2b3c4d5 HEAD@{1}: commit: Add login tests
git show 2b3c4d5                          # the version before --amend
git switch -c before-amend 2b3c4d5        # keep it on a branch if you need it

5. Recover a dropped stash

Stashes are commits too. If you dropped one recently:

git fsck --no-reflog | grep "dangling commit"
git show <hash>                           # find the one that looks like your stash
git stash apply <hash>

🧭 Safe Habits

  • Before anything risky (reset, rebase, history cleanup), create a backup branch: git branch backup-before-rebase.
  • When recovering, prefer creating a new branch at the found commit (git switch -c rescue <hash>) over resetting immediately; inspect, then decide.
  • Remember the reflog is per repository and per machine: a fresh clone has an empty reflog.

📝 Assignment

  1. Make three commits, then git reset --hard HEAD~3 and recover them with the reflog.
  2. Create and delete a branch with unmerged commits, then recover it.
  3. Rebase a branch, then undo the rebase using ORIG_HEAD or the reflog.
  4. Amend a commit and recover the original version on a new branch.
  5. Show the reflog with ISO dates and find what you did one hour ago.

❓ FAQ

🤔 What is git reflog?

A local log of every position HEAD and your branches have pointed to, which lets you find and restore commits that no longer appear in git log.

🤔 How do I recover a commit after git reset –hard?

Run git reflog, find the commit hash from before the reset, then git reset --hard <hash> or create a branch at it.

🤔 How do I recover a deleted branch in Git?

Find the branch’s last commit in git reflog and recreate it with git switch -c <branch> <hash>.

🤔 How long does Git keep the reflog?

By default about 90 days for reachable entries and 30 days for unreachable ones, configurable with gc.reflogExpire settings.

🤔 Is the reflog shared when I push?

No. The reflog exists only in your local repository.


đŸŽ¯ Next Steps

đŸŽŦ Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

1 thought on “git reflog: Recover Lost Commits, Deleted Branches and Bad Rebases”

Leave a Comment