Git empieza siendo add, commit, pull y push, pero los problemas reales aparecen cuando se pierde un commit, hay que localizar qué cambio introdujo un bug, se necesita mantener dos ramas abiertas a la vez o alguien quiere limpiar una historia antes de compartirla. Estos 12 comandos de Git, ordenados por utilidad práctica, cubren buena parte de esas situaciones y permiten trabajar con un repositorio con bastante más seguridad.
Las claves de estos 12 comandos de Git en 20 segundos
git reflogpuede localizar commits que parecen perdidos tras un reset o rebase.git restorepermite recuperar archivos sin mover la rama.git stash,bisectyworktreeresuelven problemas habituales de desarrollo y debugging.cherry-pickyrebaseayudan a gestionar cambios entre ramas.resetycleanson muy útiles, pero también los que requieren más cuidado.
El orden no responde a cuál es técnicamente más sofisticado. Prioriza el impacto que puede tener conocer cada comando cuando algo sale mal o cuando el trabajo diario empieza a complicarse.
Algunos son auténticos salvavidas. Otros evitan perder veinte minutos cambiando continuamente de rama. Y unos pocos pueden borrar trabajo si se utilizan sin entender exactamente qué modifican.
Los cuatro que pueden salvar una jornada de trabajo
1. git reflog: encontrar commits que parecían perdidos
Si hubiera que aprender un único comando fuera del flujo básico de Git, probablemente sería este.
Supongamos que una rama tiene varios commits:
9f7c21a Add payment validation
8a6e3b1 Implement PaymentService
3c7d812 Create PaymentController
Y alguien ejecuta:
git reset --hard HEAD~3
Los commits dejan de aparecer en el historial normal de la rama. Eso no significa necesariamente que hayan desaparecido inmediatamente de la base de objetos de Git.
El reflog registra los movimientos recientes de referencias como HEAD:
git reflog
Puede mostrar algo parecido a:
45bc120 HEAD@{0}: reset: moving to HEAD~3
9f7c21a HEAD@{1}: commit: Add payment validation
8a6e3b1 HEAD@{2}: commit: Implement PaymentServiceLenguaje del código: CSS (css)
Una forma prudente de recuperar el punto anterior es crear primero una rama:
git switch -c recovery 9f7c21aLenguaje del código: JavaScript (javascript)
O, si se sabe exactamente lo que se está haciendo:
git reset --hard 9f7c21a
reflog no es un backup permanente. Sus entradas pueden caducar y los objetos no alcanzables pueden terminar siendo eliminados por los mecanismos de mantenimiento de Git. Pero durante un accidente reciente suele ser uno de los primeros lugares donde mirar.
2. git restore: deshacer cambios sin mover la historia
Durante muchos años git checkout servía para demasiadas cosas: cambiar de rama, recuperar archivos y trabajar con commits concretos.
git restore ofrece una operación más explícita para recuperar contenido.
Si un fichero se ha modificado y se quiere volver a la versión que está en el índice:
git restore UserService.javaLenguaje del código: CSS (css)
Para restaurar todos los archivos modificados del directorio:
git restore .
Si un archivo se añadió accidentalmente al staging area:
git restore --staged config.ymlLenguaje del código: CSS (css)
Y para recuperar un fichero desde otro commit:
git restore --source=HEAD~2 app/config.py
Hay que recordar una diferencia importante: restaurar un archivo puede destruir modificaciones locales no guardadas.
restore resulta más preciso que utilizar reset para resolver un problema que únicamente afecta a uno o varios ficheros.
3. git stash: aparcar trabajo sin crear commits basura
Una interrupción de producción suele llegar en el peor momento.
Hay cambios todavía incompletos:
modified: OrderService.java
modified: PaymentController.java
new file: PaymentValidator.javaLenguaje del código: CSS (css)
En lugar de crear un commit llamado WIP, pueden guardarse temporalmente:
git stash push -m "payment feature"Lenguaje del código: JavaScript (javascript)
Después:
git switch main
git switch -c hotfix/login-errorLenguaje del código: JavaScript (javascript)
Cuando termina la incidencia:
git switch feature-payment
git stash popLenguaje del código: JavaScript (javascript)
Para consultar los stashes existentes:
git stash listLenguaje del código: PHP (php)
Y recuperar uno concreto sin eliminarlo de la lista:
git stash apply stash@{1}Lenguaje del código: CSS (css)
Un detalle que suele provocar sorpresas es que los archivos nuevos no rastreados no siempre se incluyen en el stash convencional. Si también se quieren guardar:
git stash -u
4. git bisect: buscar un bug mediante búsqueda binaria
Hay errores que empiezan a aparecer después de semanas de cambios y nadie sabe qué commit los introdujo.
Probar cien commits uno por uno sería absurdo.
Git puede realizar una búsqueda binaria:
git bisect start
git bisect bad
git bisect good 3a82b91
Git selecciona un commit intermedio.
Después de probarlo:
git bisect good
o:
git bisect bad
Cada respuesta reduce aproximadamente a la mitad el intervalo que queda por investigar.
Cuando termina:
git bisect reset
La función se vuelve mucho más potente cuando existe un test capaz de determinar automáticamente si cada revisión es correcta:
git bisect run ./test-login.sh
Aquí Git deja de ser únicamente un sistema de control de versiones y pasa a convertirse en una herramienta de debugging.
Los comandos que hacen mucho más manejables las ramas
5. git worktree: trabajar con varias ramas a la vez
Cambiar de rama constantemente funciona hasta que aparece una incidencia urgente mientras hay veinte archivos modificados.
worktree permite tener varias copias de trabajo asociadas al mismo repositorio:
git worktree add ../payment-hotfix hotfix/payment-error
Se obtiene algo parecido a:
project/
payment-hotfix/
El primer directorio puede continuar sobre una feature y el segundo trabajar simultáneamente sobre el hotfix.
Para verlos:
git worktree listLenguaje del código: PHP (php)
Cuando ya no se necesita uno:
git worktree remove ../payment-hotfix
Para desarrolladores que mantienen varias versiones o tienen que atender incidencias mientras trabajan en features largas, puede eliminar buena parte del continuo stash → switch → unstash.
6. git cherry-pick: traer solo el commit que hace falta
Un bug ya está corregido en develop, pero producción vive en main.
El commit es:
a72c8e1 Fix null pointer in PaymentServiceLenguaje del código: JavaScript (javascript)
No interesa fusionar todo develop.
Se puede aplicar únicamente ese cambio:
git switch main
git cherry-pick a72c8e1Lenguaje del código: JavaScript (javascript)
Git crea sobre la rama actual un nuevo commit que aplica los cambios introducidos por el original.
Es especialmente útil para hotfixes y ramas de mantenimiento.
También tiene una contrapartida: abusar de cherry-pick puede crear commits equivalentes con identificadores diferentes en varias ramas y complicar posteriormente merges y rebases.
7. git rebase -i: limpiar una rama antes de compartirla
Una feature puede terminar con una historia como esta:
fix validation
fix validation again
oops
tests
typo
really final fixLenguaje del código: PHP (php)
Antes de fusionarla puede tener sentido reorganizar sus commits:
git rebase -i HEAD~6
Git abre una lista parecida a:
pick a12bc34 Add payment API
pick b23cd45 Fix validation
pick c34de56 Add tests
Los commits pueden marcarse como:
pick
reword
edit
squash
fixup
drop
Por ejemplo:
pick a12bc34 Add payment API
fixup b23cd45 Fix validation
fixup c34de56 Fix tests
El resultado puede ser una historia mucho más legible.
Pero rebase reescribe commits.
No debería utilizarse alegremente sobre una rama pública en la que otros desarrolladores ya han basado su trabajo. La propia documentación de Git advierte del problema que supone reescribir una rama utilizada por terceros.
8. git log --graph: entender por fin qué ha ocurrido con las ramas
Un git log convencional puede resultar poco útil en un repositorio con merges y muchas ramas.
Esta variante ayuda bastante:
git log --oneline --graph --decorate --all
Ejemplo:
* c843bd1 (HEAD -> main) Merge feature/payment
|\
| * 7ae31f0 Add payment validation
| * 613a8aa Create PaymentService
|/
* 4b19d83 Previous release
--oneline reduce cada commit a una línea.
--graph representa las bifurcaciones.
--decorate muestra ramas y tags.
--all incorpora otras referencias al gráfico.
No modifica absolutamente nada. Solo permite entender mejor qué se tiene delante antes de empezar a modificarlo.
Cuatro herramientas para investigar, comparar y limpiar
9. git range-diff: comparar dos versiones de una misma serie de commits
Es uno de los comandos menos conocidos de esta lista y especialmente útil después de modificar una rama mediante rebase.
Supongamos que se ha enviado una serie de commits para revisión y posteriormente se ha rehecho sobre una nueva base.
Un diff convencional compara archivos.
range-diff compara series de commits:
git range-diff main..feature-v1 main..feature-v2Lenguaje del código: CSS (css)
Esto ayuda a responder una pregunta muy concreta:
¿Qué ha cambiado entre la versión anterior de esta serie de commits y la nueva?
Resulta útil en revisiones de código grandes, ramas rebased y series de parches donde mirar exclusivamente el estado final del repositorio oculta cambios importantes.
10. git blame: saber qué commit introdujo una línea
El nombre del comando invita a utilizarlo para descubrir «quién tiene la culpa», pero su uso útil es otro: encontrar el contexto histórico de una línea.
git blame UserService.javaLenguaje del código: CSS (css)
Puede devolver:
3a7b1c2 (Rahul 2026-03-10) public void login()
a1b8d91 (Anita 2026-04-02) validateCredentials();
c8f7e20 (David 2026-04-15) generateJwtToken();Lenguaje del código: JavaScript (javascript)
Lo verdaderamente interesante es el hash.
Después puede inspeccionarse:
git show c8f7e20
Así se descubre qué otros archivos cambiaron, cuál era el mensaje del commit y qué problema intentaba solucionar.
blame debería servir para buscar contexto, no culpables.
11. git reset: mover HEAD, el índice o ambos
reset es enormemente útil precisamente porque puede modificar varias partes del estado de Git.
Para retirar el último commit manteniendo sus cambios preparados:
git reset --soft HEAD~1
Para mantener los cambios en los archivos pero sacarlos del staging area:
git reset --mixed HEAD~1
--mixed es el comportamiento predeterminado:
git reset HEAD~1
Y el peligroso:
git reset --hard HEAD~1
--hard hace coincidir HEAD, índice y árbol de trabajo con el commit elegido. Las modificaciones locales no guardadas pueden perderse.
Hay una distinción útil entre tres comandos que suelen confundirse:
| Comando | Uso principal |
|---|---|
git restore | Recuperar archivos o contenido del índice |
git reset | Mover una referencia y/o modificar índice y archivos |
git revert | Crear un nuevo commit que deshace otro commit |
Para cambios que ya están publicados y compartidos normalmente resulta más seguro estudiar git revert antes que reescribir el historial con reset.
12. git clean: borrar lo que Git no está siguiendo
git clean puede dejar un repositorio impecable.
También puede borrar archivos que no tienen ninguna copia dentro de Git.
Por eso el comando más importante es primero:
git clean -n
-n realiza una simulación y muestra lo que eliminaría.
Después:
git clean -f
elimina archivos no rastreados.
Para incluir directorios:
git clean -fd
Y existe una opción todavía más agresiva:
git clean -fdx
-x también incluye archivos ignorados mediante .gitignore, lo que puede eliminar dependencias instaladas, builds locales, configuraciones y otros directorios generados.
La diferencia con un commit perdido es especialmente importante. Un commit puede aparecer en reflog. Un archivo nunca añadido al repositorio que se elimina con git clean no tiene por qué existir en ningún objeto recuperable de Git.
Por eso git clean -n debería convertirse casi en un reflejo muscular antes de ejecutar la eliminación real.
Una tabla rápida para saber cuál utilizar
| Prioridad | Comando | Para qué sirve | Riesgo |
|---|---|---|---|
| 1 | git reflog | Recuperar referencias y localizar trabajo perdido | Bajo |
| 2 | git restore | Recuperar archivos | Medio |
| 3 | git stash | Aparcar cambios temporalmente | Bajo |
| 4 | git bisect | Encontrar el commit que introdujo un bug | Bajo |
| 5 | git worktree | Mantener varias ramas abiertas | Bajo |
| 6 | git cherry-pick | Aplicar un commit concreto en otra rama | Medio |
| 7 | git rebase -i | Reorganizar y limpiar commits | Alto si la rama está compartida |
| 8 | git log --graph | Visualizar la historia | Ninguno |
| 9 | git range-diff | Comparar dos series de commits | Ninguno |
| 10 | git blame | Encontrar el origen de líneas concretas | Ninguno |
| 11 | git reset | Mover HEAD y modificar índice o archivos | Alto |
| 12 | git clean | Eliminar archivos no rastreados | Muy alto |
La tabla también explica por qué clean y reset aparecen al final pese a su utilidad. No son menos importantes. Son los que más merece la pena aprender antes de ejecutarlos sin opciones de seguridad.
La diferencia entre alguien que «sabe Git» y alguien que puede desenvolverse cuando Git empieza a complicarse tampoco está en memorizar docenas de parámetros.
Está en saber qué capa se está modificando.
Git mantiene, entre otras cosas, el repositorio de objetos, referencias como HEAD, el índice o staging area y el árbol de trabajo. Muchos comportamientos que parecen misteriosos dejan de serlo cuando se sabe cuál de esas partes está tocando cada comando.
restore afecta principalmente a archivos.
reset puede mover la rama.
reflog cuenta dónde estuvieron las referencias.
bisect utiliza la propia historia para depurar.
worktree permite proyectar varias ramas del mismo repositorio en directorios independientes.
Una vez se entiende esa diferencia, Git deja de parecer una colección de conjuros para convertirse en una herramienta bastante más predecible.
Preguntas frecuentes
¿Cuál es el comando de Git más importante para recuperar trabajo perdido?
git reflog suele ser el primero que conviene comprobar cuando un commit ha desaparecido después de un reset, rebase o cambio de referencia. No sustituye a un backup y sus registros no se conservan indefinidamente.
¿Cuál es la diferencia entre git restore y git reset?
git restore está pensado principalmente para restaurar archivos en el árbol de trabajo o el índice. git reset puede además mover la referencia actual y reescribir el estado de una rama.
¿Qué comandos de Git pueden provocar pérdida de trabajo?
Especialmente git reset --hard, git clean -f y determinadas operaciones de restore pueden eliminar modificaciones locales. git rebase también puede complicar una rama compartida porque reescribe commits.
¿Qué comando de Git sirve para encontrar qué commit introdujo un bug?
git bisect realiza una búsqueda binaria entre un commit conocido como correcto y otro conocido como incorrecto. También puede ejecutar automáticamente un script de pruebas con git bisect run.






