Git - Reflog & Recovery

Advanced

Git reflog is your safety netβ€”it records every change to HEAD in your repository. When you think you've lost commits, reflog is usually your path to recovery. Understanding reflog can save you from Git disasters.

What is Git Reflog?

Reflog (reference log) maintains a history of when the tips of branches and other references were updated. It's like a time machine for your repository:

HEAD Movement History:
HEAD@{0} β†’ Current position
HEAD@{1} β†’ Previous position  
HEAD@{2} β†’ Position before that
HEAD@{3} β†’ And so on...

Key characteristics:

  • Local only: Not shared between repositories
  • Time-limited: Entries expire (default 90 days)
  • Branch-specific: Each branch has its own reflog
  • Comprehensive: Records all HEAD movements

Viewing Reflog

Basic Reflog Commands

# Show reflog for current branch
git reflog

# Show reflog for specific branch
git reflog main

# Show reflog with dates
git reflog --date=iso

# Show reflog with relative dates
git reflog --date=relative
Example reflog output:
d4e5f6g (HEAD -> main) HEAD@{0}: commit: Add user authentication
c3d4e5f HEAD@{1}: pull: Fast-forward
b2c3d4e HEAD@{2}: reset: moving to HEAD~1
a1b2c3d HEAD@{3}: commit: Fix styling bug
e5f6g7h HEAD@{4}: checkout: moving from feature-branch to main
f6g7h8i HEAD@{5}: commit: Complete feature implementation
g7h8i9j HEAD@{6}: rebase finished: returning to refs/heads/feature-branch

Understanding Reflog Entries

Each reflog entry shows:

  • Commit hash: Where HEAD was pointing
  • Reference: HEAD@{n} notation
  • Action: What command caused the change
  • Message: Description of the action
Common reflog actions:
commit:         New commit created
reset:          HEAD moved with git reset
pull:           Changes pulled from remote
merge:          Branches merged
rebase:         Interactive or regular rebase
checkout:       Branch switched
cherry-pick:    Commit cherry-picked
clone:          Repository cloned

Recovery Scenarios

Scenario 1: Accidental Hard Reset

Problem:
# Accidentally destroyed last 3 commits
git reset --hard HEAD~3
Recovery:
# 1. Check reflog to find lost commits
git reflog

# Look for entry before the reset:
# a1b2c3d HEAD@{1}: commit: Important feature

# 2. Reset back to that commit
git reset --hard HEAD@{1}

# Or use the commit hash directly
git reset --hard a1b2c3d

Scenario 2: Lost Branch After Merge

Problem:
# Merged feature branch and deleted it
git merge feature-important
git branch -D feature-important

# Later realized you need the branch back
Recovery:
# 1. Find the branch in reflog
git reflog --all | grep feature-important

# 2. Recreate branch from reflog entry
git branch feature-important HEAD@{5}

# Or if you find the commit hash
git branch feature-important a1b2c3d

Scenario 3: Failed Rebase Recovery

Problem:
# Rebase went wrong, conflicts everywhere
git rebase main
# ... conflicts ...
git rebase --abort  # But this doesn't restore everything
Recovery:
# 1. Check reflog for state before rebase
git reflog

# Look for: HEAD@{3}: rebase started
# Previous entry shows original state

# 2. Reset to pre-rebase state
git reset --hard HEAD@{4}

Advanced Reflog Usage

Filtering Reflog Entries

# Show only commits (exclude other actions)
git reflog --grep="commit"

# Show entries from specific timeframe
git reflog --since="2 hours ago"
git reflog --until="yesterday"

# Show entries with patch information
git reflog -p

Branch-Specific Reflogs

# Show reflog for specific branch
git reflog refs/heads/main

# Show reflog for remote tracking branch
git reflog refs/remotes/origin/main

# Show all reflog entries for all references
git reflog --all

Recovery Techniques

Interactive Recovery

# Use git log with reflog to see full history
git log --walk-reflogs --oneline

# Show unreachable commits
git fsck --unreachable

# Find specific content in lost commits
git log --all --full-history -S"lost content"

Creating Recovery Branches

Safe recovery approach:
# 1. Create recovery branch instead of resetting
git branch recovery-branch HEAD@{3}

# 2. Switch to recovery branch to examine
git switch recovery-branch

# 3. Check if this is what you want
git log --oneline -10

# 4. If correct, merge back or reset main
git switch main
git reset --hard recovery-branch

# 5. Clean up
git branch -d recovery-branch

Reflog Configuration

Expiration Settings

# Default settings (don't change unless necessary)
git config --global gc.reflogExpire 90.days
git config --global gc.reflogExpireUnreachable 30.days

# Check current settings
git config --get gc.reflogExpire

# Disable expiration (not recommended)
git config --global gc.reflogExpire never

Reflog for Worktrees

# Each worktree has separate reflog
git worktree add ../feature-worktree feature-branch
cd ../feature-worktree
git reflog  # Shows reflog for this worktree

Emergency Recovery Procedures

Complete Disaster Recovery

When everything seems lost:
# 1. DON'T PANIC - Git rarely loses data
# 2. Check reflog first
git reflog --all

# 3. Look for unreachable objects
git fsck --full --unreachable

# 4. Find recent commits
git log --all --oneline --since="1 week ago"

# 5. Search for specific content
git grep -n "important function" $(git fsck --unreachable | grep commit | cut -d' ' -f3)

# 6. Create branches for suspicious commits
git branch maybe-important COMMIT_HASH

Reflog Repair

# If reflog is corrupted
git reflog expire --expire=now --all
git reflog --all

# Rebuild reflog from scratch (loses history)
rm -rf .git/logs/
git reflog expire --expire=now --all
Warning: Reflog repair commands can permanently delete recovery information. Only use as last resort.

Prevention is Better than Recovery

Safe Practices

  • βœ… Create backup branches before dangerous operations
  • βœ… Use git stash for temporary work
  • βœ… Push important branches to remote
  • βœ… Commit frequently, even with temporary messages
  • βœ… Use --dry-run for destructive commands
Pre-operation backup:
# Before risky operations
git branch backup-$(date +%Y%m%d-%H%M%S)

# Or tag important states
git tag before-big-change

# Push backups to remote
git push origin backup-$(date +%Y%m%d-%H%M%S)

Monitoring Repository Health

# Regular repository checks
git fsck --full
git gc --prune=now

# Check for corruption
git verify-pack -v .git/objects/pack/*.idx

# Monitor reflog size
du -sh .git/logs/

Reflog Limitations

What Reflog Cannot Recover

  • ❌ Uncommitted changes (working directory)
  • ❌ Untracked files that were never added
  • ❌ Commits from other repositories
  • ❌ Expired reflog entries
  • ❌ Reflogs from deleted repositories

When Reflog Doesn't Help

Alternative recovery methods:
# File-level recovery
git show HEAD:filename > recovered-file.txt

# Search in all commits
git log --all --full-history -- filename

# Use file system backups
# Use IDE history features
# Check backup services (Time Machine, etc.)

Practical Recovery Examples

Example 1: Recover Deleted Commits

Step-by-step recovery:
# 1. Find the lost commits
git reflog --oneline | head -20

# 2. Identify the commit you want
# e.g., a1b2c3d HEAD@{5}: commit: Lost important work

# 3. Create recovery branch
git branch recovery a1b2c3d

# 4. Verify it's correct
git log recovery --oneline -5

# 5. Merge back if satisfied
git merge recovery

Example 2: Undo Bad Merge

# Bad merge happened
git reflog | grep merge

# Found: b2c3d4e HEAD@{2}: merge feature: Merge made by 'ort' strategy

# Go back to before merge
git reset --hard HEAD@{3}

# Verify state
git log --oneline -5

Summary

You now understand Git reflog and recovery:

  • βœ… Reflog records every HEAD movement locally
  • βœ… git reflog shows history of changes
  • βœ… HEAD@{n} notation references historical states
  • βœ… Most "lost" commits can be recovered via reflog
  • βœ… Create backup branches before risky operations
  • βœ… Reflog has limitationsβ€”prevention is better
  • βœ… Emergency procedures exist for disaster recovery

Next Steps

Now that you understand recovery, let's explore advanced Git operations like rebasing:

β†’ Git - Advanced Branching

Practice Tip: Intentionally "break" a test repository and practice recovery techniques. Knowing reflog can save hours of lost work in real projects.