What's Actually Happening

Git reflog (reference log) records every change to HEAD - commits, resets, checkouts, merges, rebases. This creates a safety net: even if you delete commits or reset away work, reflog remembers where HEAD was. Entries expire after ~90 days, giving you time to recover lost work.

When You Need Reflog

  1. 1.Common scenarios:
  2. 2.Accidental reset - git reset --hard removed commits you wanted
  3. 3.Bad rebase - Rebase went wrong and lost commits
  4. 4.Deleted branch - Branch with unpushed work was deleted
  5. 5.Amend overwritten - git commit --amend replaced a commit you needed
  6. 6.Detached HEAD commits - Commits made in detached state and then abandoned

Step 1: View the Reflog

bash
git reflog

Shows recent HEAD movements:

bash
abc123d HEAD@{0}: reset: moving to HEAD~2
def4567 HEAD@{1}: commit: Important work I lost
ghi890j HEAD@{2}: commit: Previous commit
abc123d HEAD@{3}: checkout: moving from main to abc123d

Each entry shows: - Commit hash where HEAD was - HEAD@{n} - index number for reference - Action that moved HEAD - Description of that action

Step 2: Find Your Lost Commit

Look through reflog for the commit you want:

```bash # Show more entries git reflog show HEAD -20

# Search for specific action git reflog show HEAD --grep="commit"

# Show timestamps git reflog show HEAD --date=iso ```

In our example, def4567 at HEAD@{1} is the lost commit.

Step 3: Recover the Commit

Create a branch pointing to the lost commit:

```bash # Recover using HEAD@{n} reference git branch recovered-work HEAD@{1}

# Or using commit hash directly git branch recovered-work def4567

# Switch to recovered branch git checkout recovered-work ```

Now verify your work is restored:

bash
git log --oneline -3

Shows recovered commits.

Step 4: Recover from Reset --hard

If you ran git reset --hard and lost work:

```bash # Example: you did this git reset --hard HEAD~3

# Check reflog git reflog # Output: # abc123d HEAD@{0}: reset: moving to HEAD~3 # old123 HEAD@{1}: commit: Third commit (lost) # old456 HEAD@{2}: commit: Second commit (lost) # old789 HEAD@{3}: commit: First commit (lost) # abc123d HEAD@{4}: checkout: moving to main

# Recover to state before reset git reset --hard HEAD@{1} # Or create branch git branch recovery HEAD@{1} ```

Step 5: Recover After Bad Rebase

If rebase went wrong:

```bash # You aborted rebase but commits missing git rebase --abort

# Check reflog git reflog # Look for "rebase: checkout" or "rebase finished"

# Find ORIG_HEAD (saved by rebase before starting) git show ORIG_HEAD

# Reset to pre-rebase state git reset --hard ORIG_HEAD ```

Step 6: Recover Deleted Branch

If you deleted a branch with unpushed commits:

```bash # Oops: git branch -D feature-branch

# Reflog still has entries git reflog # Find commits from deleted branch # Example: def4567 HEAD@{5}: checkout: moving from feature-branch to main

# Recreate branch at that commit git branch feature-branch-recovered def4567 ```

Step 7: Recover After Commit --amend

If amend overwrote a commit you needed:

```bash # Original commit was abc123d # You amended it to def4567

git reflog # Shows both: # def4567 HEAD@{0}: commit (amend): Amended version # abc123d HEAD@{1}: commit: Original commit

# Recover original git branch original-commit abc123d ```

Step 8: Cherry-Pick Specific Lost Commit

If you want to bring back just one commit:

```bash # Find commit hash from reflog git reflog | grep "some message"

# Cherry-pick it onto current branch git cherry-pick abc123d

# Or create branch from it git checkout -b recovered abc123d ```

Step 9: Check Reflog Expiry

Reflog entries expire after 90 days by default:

```bash # Check expiry settings git config --get gc.reflogExpire git config --get gc.reflogExpireUnreachable

# Set longer expiry git config --global gc.reflogExpire "180 days" ```

Verify the Fix

After recovery:

```bash # Check branch exists git branch -a

# Check commits are there git log --oneline recovered-work

# Verify file content git show recovered-work:path/to/file ```

Prevention Tips

Before risky operations, create backup:

```bash # Create backup branch before reset git branch backup-point

# Before risky rebase git branch pre-rebase-backup ```

If something goes wrong, you have the backup branch.