2 min de lectura
git checkout -: cómo sabe Git cuál era tu rama anterior
git checkout - te devuelve a la rama en la que estabas antes, igual que cd - en la terminal. No es magia: Git lo lee del reflog de HEAD. Te explico qué pasa por dentro y cuándo falla.
Estás en feature/login, saltas a main para revisar algo y quieres volver. Puedes escribir el nombre completo de la rama, o puedes escribir esto:
git checkout -Ese guion significa "la rama donde estaba justo antes". Si lo repites, vuelves otra vez: funciona como un interruptor entre las dos últimas ramas. Es la misma idea que cd - en la terminal.
El guion es un atajo de @{-1}
Git no trata el guion como algo especial de checkout. Lo traduce a @{-1}, que se lee "la rama que tenía activa un cambio atrás". Estos dos comandos hacen lo mismo:
git checkout -
git checkout @{-1}El número se puede cambiar. @{-2} es la rama de hace dos cambios, @{-3} la de hace tres, y así.
De dónde saca Git esa información
Git no guarda una variable con "la rama anterior". Lo que tiene es el reflog de HEAD: un registro local de cada movimiento de HEAD. Cada vez que cambias de rama, Git añade una línea. Puedes verlo así:
git reflog
a1b2c3d HEAD@{0}: checkout: moving from feature/login to main
9f8e7d6 HEAD@{1}: commit: agrega validación al formulario
4c5d6e7 HEAD@{2}: checkout: moving from main to feature/loginCuando escribes git checkout -, Git recorre ese registro desde lo más reciente, busca la primera línea que diga checkout: moving from X to Y y toma la X. En el ejemplo, la X es feature/login, así que ahí te lleva.
Por eso al repetir el comando alternas: el cambio que acabas de hacer también queda registrado, y ahora la X es la rama de la que vienes.
No solo sirve con checkout
git switch -cambia a la rama anterior, igual que checkout.
git merge -fusiona la rama anterior en la actual.
git rebase -reorganiza la rama actual sobre la anterior.
Un flujo muy común: terminas en tu rama, pasas a main, y fusionas sin escribir el nombre.
git checkout main
git merge -Cuándo falla
No hay rama anterior.
En un repositorio recién clonado o recién creado todavía no has cambiado de rama, así que Git no tiene nada que leer y responde con un error.
Borraste la rama anterior.
El reflog recuerda el nombre, pero la rama ya no existe.
Venías de un commit suelto.
Si antes estabas en un commit concreto y no en una rama (HEAD separado), el guion te devuelve a ese commit, otra vez en HEAD separado.
Es local.
El reflog no se sube con
git push. Cada copia del repositorio tiene su propia historia de cambios de rama.
En resumen
git checkout - es un atajo de git checkout @{-1}. Git encuentra la rama anterior leyendo el reflog de HEAD, donde queda anotado cada cambio de rama. Mientras esa anotación exista y la rama siga viva, el guion te lleva de vuelta.