TechLead
Lección 8 de 9
5 min de lectura
Git Avanzado

Reflog y recuperación

Usa el reflog para recuperar commits, ramas y deshacer casi cualquier error.

Entendiendo el Reflog

El reflog (reference log) registra cuándo cambian los tips de ramas y HEAD. Es tu red de seguridad para recuperar casi cualquier error.

Ver el reflog

# View HEAD reflog
git reflog

# View specific branch reflog
git reflog show main

# View with timestamps
git reflog --date=relative

# View with full commit info
git reflog --format=fuller

# View reflog for specific ref
git reflog show stash

Salida del reflog

abc1234 HEAD@{0}: commit: Add new feature
def5678 HEAD@{1}: checkout: moving from main to feature
ghi9012 HEAD@{2}: reset: moving to HEAD~3
jkl3456 HEAD@{3}: commit: Previous work
mno7890 HEAD@{4}: merge feature: Fast-forward

Recuperar commits perdidos

# After accidental reset
git reset --hard HEAD~3

# Find lost commits
git reflog
# Find: abc1234 HEAD@{1}: commit: Important work

# Recover
git reset --hard abc1234

# Or create new branch with lost commit
git branch recovered abc1234

Recuperar una rama eliminada

# Accidentally deleted branch
git branch -D feature-branch

# Find the last commit
git reflog | grep feature-branch
# Or: git reflog | grep checkout.*feature

# Recreate branch
git branch feature-branch abc1234

Deshacer un rebase fallido

# After disastrous rebase
git rebase main
# Creates mess...

# Find pre-rebase state
git reflog
# Look for: HEAD@{5}: rebase started

# Reset to before rebase
git reset --hard HEAD@{5}

# Or use ORIG_HEAD (set before rebase)
git reset --hard ORIG_HEAD

Recuperar stash

# Accidentally dropped stash
git stash drop

# Find in reflog
git fsck --unreachable | grep commit

# Or search stash reflog
git reflog show stash

# Recover stash
git stash apply abc1234

Encontrar trabajo perdido

# Find all unreachable commits
git fsck --lost-found

# Commits are in .git/lost-found/commit/

# Search for specific content
git log --all --full-history -- "**/deleted-file.js"

# Search commit messages
git log --all --oneline | grep "keyword"

# Search in reflog
git reflog | grep "keyword"

Escenarios de recuperación

# Scenario 1: Recover from bad merge
git reflog
git reset --hard HEAD@{1}

# Scenario 2: Recover amended commit
git reflog
# Old commit is HEAD@{1}
git branch recovered-original HEAD@{1}

# Scenario 3: Recover from reset --hard
git reflog
git reset --hard HEAD@{n}  # n = steps back

# Scenario 4: Recover file version
git checkout HEAD@{5} -- path/to/file.js

Expiración del reflog

# Default: 90 days for reachable, 30 for unreachable

# View expiration settings
git config gc.reflogExpire
git config gc.reflogExpireUnreachable

# Change expiration
git config gc.reflogExpire "180 days"
git config gc.reflogExpireUnreachable "90 days"

# Expire old entries manually
git reflog expire --expire=90.days.ago --all

# Never expire (not recommended)
git config gc.reflogExpire never

ORIG_HEAD y otras refs

# ORIG_HEAD - set before dangerous operations
git reset --hard ORIG_HEAD

# MERGE_HEAD - during merge
cat .git/MERGE_HEAD

# FETCH_HEAD - last fetch
git log FETCH_HEAD

# CHERRY_PICK_HEAD - during cherry-pick
cat .git/CHERRY_PICK_HEAD

Medidas preventivas

# Create backup branch before risky operations
git branch backup

# Use --dry-run when available
git clean -n  # Instead of git clean -f

# Check what will be affected
git log HEAD..origin/main  # Before pull
git log origin/main..HEAD  # Before push

# Enable rerere for conflict resolution memory
git config rerere.enabled true

Cuando el reflog no puede ayudar

  • Cambios sin commit perdidos con reset --hard
  • Entradas del reflog expiradas (después de gc)
  • Trabajar con repositorios bare
  • Archivos nunca stageados ni commiteados

Buenas prácticas

  • Commitea a menudo, incluso WIP
  • Crea ramas antes de experimentar
  • Conoce tu reflog antes de operaciones destructivas
  • Considera ampliar expiración del reflog en repos importantes

Continuar aprendiendo