Día 30 - Limpiar historial de commits con git reset
Problema / Desafío
El equipo de desarrollo de Nautilus tiene un repositorio de pruebas en /usr/src/kodekloudrepos/games (Storage server, Stratos DC). Se hicieron varios commits de prueba y ahora quieren limpiar el repositorio dejando únicamente dos commits en el historial:
initial commitadd data.txt file
Cualquier commit posterior debe eliminarse del historial y el remote debe actualizarse.
Conceptos clave
git reset vs git revert
| Característica | git reset |
git revert |
|---|---|---|
| Qué hace | Mueve el puntero HEAD (y el branch) a un commit anterior | Crea un nuevo commit que deshace cambios |
| Historial | Destruye commits posteriores al punto elegido | Preserva todo el historial |
| Requiere force push | Sí (el remote queda adelante) | No |
| Uso recomendado | Ramas locales o de prueba | Ramas compartidas / produccion |
| Recuperable | Solo via git reflog (~90 días) |
Siempre visible en el log |
En este caso git reset es la opcion correcta porque el objetivo explícito es eliminar el historial de commits de prueba.
Modos de git reset
git reset --soft <hash> # Mueve HEAD, conserva cambios en staging
git reset --mixed <hash> # Mueve HEAD, conserva cambios en working tree (default)
git reset --hard <hash> # Mueve HEAD, DESCARTA todos los cambios
Para limpiar completamente se usa --hard — el working tree queda identico al estado del commit destino.
Por qué se necesita force push
Antes del reset:
remote: A → B → C → D (HEAD)
local: A → B → C → D (HEAD)
Después del git reset --hard B:
remote: A → B → C → D (HEAD) ← el remote sigue adelante
local: A → B (HEAD) ← el local retrocedió
git push normal falla porque el remote está "más adelante".
git push --force sobreescribe el remote con el estado local.
Pasos
- Conectarse al Storage server
- Ir al repositorio
/usr/src/kodekloudrepos/games - Revisar el historial de commits con
git log - Identificar el hash del commit
add data.txt file - Ejecutar
git reset --hard <hash>para apuntar HEAD a ese commit - Verificar que el historial quedó con solo dos commits
- Hacer
git push --forcepara actualizar el remote
Comandos / Código
1. Conectarse al servidor y navegar al repo
2. Revisar el historial completo
Salida de ejemplo (antes del reset):
f3a2d1c (HEAD -> master, origin/master) added test data
8b4e9f2 modified data.txt
a1c3e5d add data.txt file
2b7f8a1 initial commit
Se necesita el hash del commit add data.txt file → a1c3e5d.
3. Ejecutar el reset
4. Verificar el historial después del reset
Solo quedan los dos commits requeridos.
5. Force push al remote
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To <remote-url>
+ f3a2d1c...a1c3e5d master -> master (forced update)
Verificación final
a1c3e5d (HEAD -> master, origin/master) add data.txt file
2b7f8a1 initial commit
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
Diferencia entre --hard, --mixed y --soft aplicado a este caso
# --soft: HEAD retrocede, pero los archivos de los commits eliminados
# quedan en staging listos para un nuevo commit
git reset --soft a1c3e5d
git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: data.txt
new file: test.txt
Los cambios de los commits eliminados aparecen en staging — listos para un git commit inmediato.
# --mixed (default): HEAD retrocede, archivos quedan en working tree
# pero no en staging
git reset --mixed a1c3e5d
git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: data.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
test.txt
Los archivos existen en el directorio pero Git no los tiene en staging — hay que hacer git add antes de poder commitear.
# --hard: HEAD retrocede, working tree y staging quedan igual al commit
# destino — archivos de commits eliminados desaparecen
git reset --hard a1c3e5d
git status
El directorio queda identico al estado del commit destino. Los archivos de los commits eliminados no existen en ningún lado (salvo en git reflog).
Troubleshooting
| Problema | Solucion |
|---|---|
git push rechazado con rejected (non-fast-forward) |
El remote tiene commits que el local no — usar git push --force o git push -f |
| Se usó el hash incorrecto | Verificar con git reflog y volver a hacer el reset con el hash correcto |
git push -f rechazado (branch protegido) |
El branch tiene proteccion de force push en el servidor — desactivarla desde la UI del repo o con permisos de admin |
| Se perdieron cambios que no debían perderse | Buscar en git reflog el hash del commit perdido y hacer git cherry-pick o git reset --hard <hash-anterior> |