git reset
git reset: restablece HEAD y la rama actual a un commit distinto.
git reset mueve sobre todo HEAD y la rama actual hasta un commit concreto; en la práctica, "rebobina" el historial del proyecto a un estado anterior. Resulta útil cuando necesitas retirar de la rama commits que ya has creado.
Cuando usas git reset, es como decirle a tu repositorio que trate un estado anterior como el estado actual del proyecto. Viene muy bien para mover el puntero de una rama, simplificar historiales enrevesados o incluso combinar varios commits en uno antes de compartirlos con otras personas.
Históricamente, git reset se usaba para varias cosas, entre ellas restablecer el directorio de trabajo y el área de staging. A día de hoy, muchos desarrolladores veteranos siguen usando git reset para esas tareas. Sin embargo, desde la llegada de git restore en Git 2.23.0, ahora se recomienda usar git restore para gestionar el directorio de trabajo y el área de staging, mientras que git reset debería usarse sobre todo para mover HEAD y el puntero de la rama actual.
Con git restore hay menos riesgo de romper algo por accidente, porque es más específico y menos destructivo que git reset. Si ya tienes la costumbre de usar el viejo git reset, quizá tardes un poco en acostumbrarte al nuevo comando. Pero si Git todavía te suena nuevo, merece la pena entender la diferencia e intentar usar git restore en vez de git reset cuando encaje.
Ejemplos
Mover la rama actual un commit hacia atrás y restablecer el área de staging para que coincida con ese commit, pero sin cambiar el directorio de trabajo. Los cambios del commit que ha quedado fuera del historial de la rama pasan a estar fuera de staging.
Un caso de uso habitual es dividir un commit hecho con prisas en varios commits más concretos o volver a añadir solo una parte a staging:
git reset HEAD~1Mover la rama actual tres commits hacia atrás sin cambiar el área de staging ni el directorio de trabajo. Los cambios de esos commits aparecen juntos en staging.
Un caso de uso habitual es sustituir varios commits locales pequeños o desordenados por un único commit limpio:
git reset --soft HEAD~3Mover la rama actual dos commits hacia atrás y restablecer tanto el área de staging como el directorio de trabajo para que coincidan con ese commit anterior. Esto descarta los cambios de esos commits y cualquier cambio sin commit en archivos con seguimiento. Los cambios sin commit pueden perderse para siempre.
Un caso de uso habitual es abandonar por completo un experimento local cuando tienes claro que no necesitas sus commits ni sus cambios en archivos con seguimiento:
git reset --hard HEAD~2En estos ejemplos, HEAD~1 significa "un commit antes de HEAD". El número que aparece después de ~ indica cuántos commits debe retroceder Git, así que HEAD~3 significa "tres commits antes de HEAD". También puedes indicar el destino mediante un hash de commit, una rama u otra referencia a un commit.
Ten cuidado al usar git reset, sobre todo con la opción --hard, porque puede descartar cambios de forma permanente. Comprueba siempre que estás restableciendo la rama al commit correcto y plantéate usar git stash para guardar tus cambios sin incluir en un commit antes de restablecer la rama si crees que podrías necesitarlos más tarde.
Ten en cuenta que git reset no elimina commits por completo; en realidad, solo mueve el puntero de la rama. Los commits "eliminados" siguen en el historial del repositorio (puedes acceder a ellos mediante su hash de commit), pero ya no son alcanzables desde la rama actual. Esto significa que puedes recuperarlos si hace falta, aunque ya no aparecerán en el historial de la rama.
.gitignoregit checkoutgit configgit taggit worktree