HDP115

Reflog y recuperación de commits perdidos

Aprende a utilizar git reflog para rastrear cambios en tu repositorio y recuperar commits aparentemente perdidos después de operaciones como reset, rebase o branch deletion.

CE

Cristian Escalante

Última actualización: 2 de mayo de 2025

git
control de versiones
desarrollo
recuperación

Reflog y recuperación de commits perdidos

Una de las características más poderosas pero menos conocidas de Git es su capacidad para recuperar trabajo que parece haberse perdido. Ya sea que hayas hecho un git reset --hard por error, un rebase que salió mal, o eliminado una rama sin fusionar, Git proporciona herramientas para ayudarte a recuperar tu trabajo. La más importante de estas herramientas es el reflog.

¿Qué es el reflog?

El reflog (registro de referencias) es un mecanismo que Git utiliza para registrar actualizaciones a las puntas de las ramas y otras referencias. Cada vez que la referencia HEAD cambia (por ejemplo, cuando haces checkout a otra rama, commit, reset, etc.), Git registra esa información en el reflog.

A diferencia del historial normal de commits que puedes ver con git log, el reflog es:

  1. Local: Solo existe en tu repositorio local y no se comparte al hacer push
  2. Temporal: Las entradas del reflog tienen una vida limitada (por defecto, 90 días)
  3. Completo: Registra todas las acciones, incluso aquellas que parecen destructivas

Visualizando el reflog

Para ver el reflog, simplemente ejecuta:

git reflog

La salida se verá algo así:

734713b (HEAD -> main) HEAD@{0}: commit: Add feature X
a6f4612 HEAD@{1}: commit: Update documentation
ebfd14d HEAD@{2}: checkout: moving from feature/test to main
2c4f36d HEAD@{3}: commit: Add test feature
7289f23 HEAD@{4}: reset: moving to HEAD~1
982fb40 HEAD@{5}: commit: Add feature that was later discarded

Cada entrada incluye:

  • Un identificador de commit
  • Una notación HEAD@{n} que indica la posición en el reflog
  • La acción que causó el cambio
  • Una breve descripción

Casos comunes de pérdida de commits

1. Reset duro accidental

Si has hecho un git reset --hard y perdido commits:

# Situación: acabas de hacer un reset duro y perdiste commits
git reset --hard HEAD~3  # Oops! Perdiste 3 commits

# Solución: usa reflog para ver los commits recientes
git reflog

# Recupera el estado anterior al reset
git reset --hard HEAD@{1}  # O usa el hash del commit

2. Rebase que salió mal

Si un rebase causó problemas y quieres volver al estado anterior:

# Situación: un rebase complicado salió mal
git rebase -i main  # Algo salió mal durante el rebase

# Solución: aborta el rebase si aún está en progreso
git rebase --abort

# O si ya terminó, usa reflog para volver al estado anterior
git reflog
git reset --hard HEAD@{5}  # Donde HEAD@{5} es el estado antes del rebase

3. Rama eliminada accidentalmente

Si eliminaste una rama sin fusionar sus cambios:

# Situación: eliminaste una rama por error
git branch -D feature/importante  # Oops!

# Solución: encuentra el último commit de esa rama en el reflog
git reflog

# Crea una nueva rama en ese commit
git branch feature/recuperada a6f4612  # Usando el hash del último commit de la rama

4. Commit amend accidental

Si sobrescribiste un commit con --amend y quieres recuperar la versión original:

# Situación: modificaste el último commit con amend
git commit --amend  # Cambió el commit original

# Solución: encuentra el commit original en el reflog
git reflog
git reset --hard HEAD@{1}  # La versión antes del amend

Comandos avanzados de reflog

Ver el reflog de una rama específica

git reflog show main

Ver el reflog con más detalles

git reflog --date=iso

Ver el reflog con las diferencias

git reflog -p

Recuperación de commits huérfanos

Los commits "huérfanos" son aquellos que no están conectados a ninguna rama o etiqueta. Pueden crearse por varias razones, como rebase, reset, o eliminación de ramas.

Encontrar commits huérfanos

# Muestra todos los commits, incluyendo los huérfanos
git fsck --lost-found

Este comando mostrará "dangling commits" (commits huérfanos) que podrías querer recuperar.

Examinar un commit huérfano

# Ver el contenido de un commit huérfano
git show <hash-del-commit>

Recuperar un commit huérfano

# Crear una rama apuntando al commit huérfano
git branch recuperado <hash-del-commit>

Estrategias de prevención

Aunque el reflog es una red de seguridad excelente, es mejor prevenir que curar:

1. Crear ramas antes de operaciones arriesgadas

# Antes de un rebase o reset
git branch backup/antes-de-rebase

2. Usar stash para guardar cambios temporales

# Guardar cambios no confirmados
git stash save "Cambios importantes antes de experimento"

3. Hacer commits frecuentes

Los cambios confirmados son mucho más fáciles de recuperar que los no confirmados.

4. Usar reset --soft o --mixed en lugar de --hard

# En lugar de --hard, que descarta cambios
git reset --soft HEAD~1  # Mantiene los cambios en staging
git reset --mixed HEAD~1  # Mantiene los cambios en working directory

Limitaciones del reflog

Es importante entender que el reflog tiene algunas limitaciones:

  1. Es local: No se transfiere a repositorios remotos
  2. Es temporal: Las entradas más antiguas de 90 días se eliminan automáticamente
  3. No incluye archivos no rastreados: Los archivos nuevos que nunca fueron añadidos a Git no se pueden recuperar
  4. Se limpia con garbage collection: git gc puede eliminar entradas del reflog

Configuración del reflog

Puedes ajustar la configuración del reflog según tus necesidades:

# Cambiar el tiempo de expiración del reflog (por ejemplo, a 180 días)
git config --global gc.reflogExpire "180 days"

# Cambiar el tiempo de expiración para referencias no alcanzables
git config --global gc.reflogExpireUnreachable "30 days"

Flujos de trabajo de recuperación

Escenario 1: Recuperar después de un reset duro

# 1. Identifica lo que se perdió
git reflog

# 2. Examina los cambios perdidos
git show HEAD@{1}

# 3. Recupera todo el estado anterior
git reset --hard HEAD@{1}

# O crea una rama para revisar los cambios
git branch recuperacion HEAD@{1}

Escenario 2: Recuperar commits específicos después de un rebase

# 1. Encuentra los commits perdidos
git reflog

# 2. Cherry-pick los commits específicos que necesitas
git cherry-pick abc1234

# 3. O crea una rama temporal con el estado anterior
git branch temp-recuperacion HEAD@{5}

Escenario 3: Recuperar una rama eliminada

# 1. Encuentra el último commit de la rama
git reflog | grep 'nombre-de-rama'

# 2. Crea una nueva rama en ese commit
git branch nueva-rama abc1234

Herramientas complementarias

Git fsck

# Verificar la integridad del repositorio y encontrar objetos huérfanos
git fsck --full

Git gc

# Limpiar objetos innecesarios (¡cuidado! puede eliminar algunos objetos recuperables)
git gc

Git prune

# Eliminar objetos huérfanos (¡usar con extrema precaución!)
git prune

Conclusión

El reflog de Git es una herramienta invaluable para recuperar trabajo que parece haberse perdido. Funciona como una red de seguridad que registra todos los cambios en tu repositorio local, permitiéndote volver a estados anteriores incluso después de operaciones aparentemente destructivas.

Aunque es reconfortante saber que Git proporciona estas capacidades de recuperación, la mejor estrategia es siempre trabajar de manera que minimice la necesidad de usarlas. Hacer commits frecuentes, usar ramas para experimentos y comprender completamente los comandos antes de ejecutarlos te ayudará a evitar situaciones donde necesites recurrir al reflog.

Sin embargo, los errores ocurren, y cuando lo hacen, el reflog puede ser tu mejor aliado para recuperar tu trabajo y seguir adelante.

Búsqueda en el historial
Aprende técnicas avanzadas para buscar y filtrar información...
Rebase
Aprende a utilizar git rebase para mantener un historial de ...
Referencias
Git. Git - git-reflog Documentation. https://git-scm.com/docs/git-reflog
Scott Chacon and Ben Straub. Pro Git Book - Data Recovery. https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery
Atlassian. Git Pretty - Fixing Mistakes. https://www.atlassian.com/git/tutorials/rewriting-history

Conceptos Básicos de HTML

Aprende los conceptos básicos de HTML

Conceptos Básicos de CSS

Aprende los conceptos básicos de CSS

Conceptos Básicos de JavaScript

Aprende los conceptos básicos de JavaScript

Conceptos Básicos SQL

Aprende los conceptos básicos de SQL

Conceptos Básicos de Python

Aprende los conceptos básicos de Python

Conceptos Básicos de UML

Aprende los conceptos básicos de UML

Refuerzo Academico de Herramientas de Productividad 2025