git checkout
Cambiar de rama o restaurar archivos del árbol de trabajo
git checkout es un comando versátil que cambia de rama, crea ramas nuevas, restaura archivos de commits concretos y puede dejar tu repositorio en estado «HEAD separado» (detached HEAD). Aunque las versiones recientes de Git repartieron parte de sus funciones entre «git switch» y «git restore», checkout sigue siendo muy usado y conocido.
Sinopsis
git checkout <branch>
git checkout -b <new-branch> [<start-point>]
git checkout -B <branch> [<start-point>]
git checkout --detach [<branch>]
git checkout [--] <pathspec>...
git checkout <commit> -- <pathspec>...Opciones
Elegir la opción adecuada
Crear ramas
Distintas formas de crear una rama nueva y cambiarte a ella
| Comando | Si la rama existe | Historial | Ideal para |
|---|---|---|---|
-b <name> | Falla con un error | Normal (conectada) | Trabajo habitual en una funcionalidad nueva |
-B <name> | Se reinicia en el commit actual | Normal (conectada) | Empezar una rama desde cero |
--orphan <name> | Falla con un error | Ninguno (desconectada) | gh-pages, docs, empezar de cero |
Cambiar de rama con cambios sin commit
Qué pasa con tus cambios locales al cambiar de rama
| Comando | Cambios sin commit | Nivel de riesgo | Cuándo usarla |
|---|---|---|---|
git checkout <branch> | Bloqueado si hay conflicto | Seguro | Comportamiento por defecto: evita accidentes |
git checkout -f <branch> | Se descartan para siempre | Peligroso | Abandonar a propósito todos los cambios locales |
git checkout -m <branch> | Se integran con un merge a tres bandas | Media | Llevarte los cambios a otra rama |
git stash + checkout | Guardados para después | Seguro | Cambio de contexto temporal |
Restaurar archivos
Descartar o restaurar el contenido de archivos desde distintas fuentes
| Comando | Origen | Afecta a la preparación | Recuperable |
|---|---|---|---|
-- <file> | Índice (versión preparada) | No | No: los cambios se pierden para siempre |
<commit> -- <file> | Un commit concreto | Sí (preparado) | No, pero queda preparado para revisar |
-p -- <file> | Índice (interactivo) | No | Parcial: eliges los fragmentos |
Seguimiento de ramas remotas
Controlar la relación entre ramas locales y remotas
| Comando | Crea seguimiento | Caso de uso | git push/pull |
|---|---|---|---|
--track origin/feat | Sí (automático) | Trabajar en la rama de un compañero | Funciona sin argumentos |
--no-track -b exp origin/main | No (independiente) | Experimentar sin riesgo | Exige indicar el remoto |
<remote-branch> | Sí (si no hay ambigüedad) | Checkout rápido de una rama remota | Funciona sin argumentos |
Resolver conflictos de merge
Elegir un lado durante un conflicto de merge
| Comando | Conserva | Descarta | Cuándo usarla |
|---|---|---|---|
--ours <file> | La versión de tu rama | Cambios entrantes | Tus cambios son los correctos |
--theirs <file> | Versión entrante | Tus cambios | Aceptar su implementación |
(manual edit) | Resultado combinado | Nada | Necesitas partes de ambos lados |
checkout frente a los comandos modernos
Git 2.23+ dividió checkout en comandos específicos
| Comando | Cambia de rama | Restaura archivos | Recomendado para |
|---|---|---|---|
git checkout | Sí | Sí | Costumbre, versiones antiguas de Git |
git switch | Sí | No | Intención clara: solo operaciones de ramas |
git restore | No | Sí | Intención clara: solo operaciones de archivos |
Ejemplos de flujos de trabajo
git stashGuardar el trabajo actual sin commit
git checkout other-branchCambiarse a la otra rama
(review or make quick fix)Hacer el trabajo necesario en esta rama
git checkout -Volver a la rama anterior (atajo)
git stash popRecuperar el trabajo guardado
git checkout mainCambiarse a la rama main
git pull origin mainTraer los últimos cambios del remoto
git checkout -b feature-nameCrear la nueva rama de funcionalidad y cambiarse a ella
(make changes and commits)Trabajar en la funcionalidad
git push -u origin feature-nameSubir la rama y configurar el seguimiento
git statusVer qué archivos se han modificado
git diff file.jsRevisar los cambios que vas a descartar
git checkout -- file.jsDescartar los cambios de un archivo concreto
git checkout -- .O descartar TODOS los cambios sin preparar de los archivos con seguimiento
git log --onelineEncontrar el hash del commit que necesitas
git checkout <commit-hash>Hacer checkout de ese commit concreto (HEAD separado)
(inspect, test, or debug)Investigar el código antiguo
git checkout mainVolver a la rama main al terminar
git log --oneline -- file.jsEncontrar los commits que cambiaron este archivo
git show <commit>:file.jsVer la versión antigua
git checkout <commit> -- file.jsRestaurar el archivo desde ese commit (queda preparado)
git commit -m 'Restore file.js'Hacer commit de la versión restaurada
git fetch originTraer la información más reciente de las ramas remotas
git branch -rVer las ramas remotas disponibles
git checkout --track origin/featureCrear una rama local que sigue a la remota
git pullAhora pull funciona sin indicar el remoto
Solución de problemas
error: Your local changes to the following files would be overwritten by checkout
Causa: Tienes cambios sin commit que chocan con la rama de destino
Haz commit de tus cambios, guárdalos con stash o usa -f para forzar (descarta los cambios)
git stash && git checkout branch && git stash poperror: pathspec 'branch-name' did not match any file(s) known to git
Causa: La rama no existe, o quizá escribiste mal el nombre
Consulta las ramas disponibles con git branch -a, o crea la rama con -b
git branch -a | grep branch-nameYou are in 'detached HEAD' state
Causa: Hiciste checkout de un hash de commit o de una etiqueta en lugar de un nombre de rama
Si quieres seguir trabajando, crea una rama. Si no, haz checkout de una rama existente
git checkout -b new-branch-nameSe pierden los commits hechos con HEAD separado
Causa: Hiciste commits con HEAD separado y luego te cambiaste a otra rama
Encuentra los commits con el reflog y crea una rama para conservarlos
git reflog && git branch recovered-work <commit-hash>No se puede hacer checkout: se sobrescribiría un archivo sin seguimiento
Causa: Tienes archivos sin seguimiento que existen en la rama de destino
Borra, mueve o guarda con stash primero esos archivos sin seguimiento
git stash --include-untracked && git checkout branchDescartaste cambios sin querer con checkout --
Causa: git checkout -- <file> elimina para siempre los cambios sin commit
Por desgracia, Git no puede recuperarlos. Revisa el historial local de tu editor
(check IDE local history if available)fatal: 'name' could be both a local file and a tracking branch
Causa: Un archivo o carpeta tiene el mismo nombre que la rama remota de la que quieres hacer checkout
Añade un -- al final para indicar a Git que el nombre es una rama, o usa git switch
git checkout branch-name --La rama no se actualiza tras el checkout
Causa: Puede que hayas hecho checkout directamente de una rama de seguimiento remoto
Crea una rama local de seguimiento en lugar de hacer checkout directo de origin/branch
git checkout --track origin/branch-nameConsejos y trampas
Buenas prácticas
- ✓Usa 'git stash' antes de cambiar de rama si tienes trabajo sin commit que quieres conservar
- ✓Mejor 'git checkout -b' que 'git branch' + 'git checkout' por separado para crear una rama y cambiarte a ella
- ✓Usa '--' para separar claramente las rutas de archivo de los nombres de rama: 'git checkout -- file.txt'
- ✓Plantéate usar los comandos modernos 'git switch' para ramas y 'git restore' para archivos: la intención queda más clara
- ✓Usa 'git checkout -' para volver rápido a la rama anterior (como 'cd -')
- ✓Antes de usar '-f' para forzar el checkout, asegúrate de que de verdad quieres descartar tus cambios
- ✓Con HEAD separado (detached), crea una rama enseguida si piensas hacer commits
- ✓Usa '--track' al hacer checkout de ramas remotas para configurar push/pull automáticamente
- ✓Usa 'git checkout <commit> -- <file>' para restaurar archivos concretos sin cambiar de rama
- ✓Evita hacer checkout de commits directamente salvo para investigar: usa nombres de rama para el trabajo normal
- ✓Usa '-p' (modo patch) cuando quieras descartar solo algunos cambios de un archivo
- ✓Comprueba siempre que estás en la rama correcta con 'git branch' o 'git status' antes de ponerte a trabajar
Errores comunes
- ✗Intentar un checkout con cambios sin commit. Git se niega a cambiar si eso sobrescribiría tus cambios: haz commit, stash o usa -f para forzar (descarta los cambios).
- ✗Confundir checkout para ramas con checkout para archivos. Restaurar archivos sin querer al intentar cambiar de rama: pon -- antes de las rutas: git checkout -- file.txt
- ✗Hacer commits con HEAD separado (detached). Esos commits quedan huérfanos al hacer checkout de otra rama: crea antes una rama: git checkout -b my-branch
- ✗Usar -B sin entender que sobrescribe. Puede hacerte perder la posición de la rama existente: usa -b para ramas nuevas y -B solo cuando quieras reiniciarla a propósito.
Preguntas frecuentes
'git switch' es un comando más nuevo (Git 2.23+) que solo sirve para cambiar de rama, así que es más claro y seguro. 'git checkout' puede tanto cambiar de rama COMO restaurar archivos, lo que puede confundir. Usa 'git switch' para ramas y 'git restore' para archivos si prefieres el enfoque moderno.
Por desgracia, con Git solo no se puede: los cambios se descartan para siempre. Algunos IDE tienen historial local que puede ayudar. Por eso hay que tener cuidado con este comando.
HEAD separado (detached) significa que has hecho checkout de un commit concreto en lugar de una rama. Puedes curiosear y hacer commits, pero no pertenecerán a ninguna rama. Crea una rama con 'git checkout -b name' para guardar tu trabajo.
'-b' crea una rama nueva y falla si ya existe. '-B' crea una rama nueva o reinicia una existente en la posición actual. Usa '-B' cuando quieras reiniciar una rama a propósito.
Usa 'git checkout other-branch -- path/to/file'. Copia el archivo de esa rama a tu directorio de trabajo y al área de preparación. Después puedes hacer commit en tu rama actual.
Git te protege de perder trabajo. Si cambiar de rama sobrescribiría tus cambios, se niega. Haz commit de tus cambios, guárdalos con 'git stash' o usa 'git checkout -f' para forzar (lo que descarta los cambios).
Te cambia a la rama en la que estabas antes, como 'cd -' en la shell. Es una forma rápida de alternar entre dos ramas en las que trabajas.
Primero haz 'git fetch origin' y luego 'git checkout branch-name' (Git crea automáticamente una rama de seguimiento si existe origin/branch-name) o, de forma explícita, 'git checkout --track origin/branch-name'.
Sí: usa 'git checkout -p <commit> -- <file>' para el modo interactivo, o simplemente 'git checkout <commit> -- <specific-files>' para restaurar solo ciertos archivos de ese commit.
Porque hace dos cosas muy distintas: cambiar de rama Y restaurar archivos. Git 2.23 introdujo 'git switch' y 'git restore' para separar esas tareas. 'git checkout' sigue funcionando y se usa muchísimo.