Cambie temporalmente la copia de trabajo a una confirmación Git específica

248

¿Cómo cambiar a una confirmación específica de Git sin perder todas las confirmaciones realizadas después ?

Quiero que se cambien los archivos locales, pero la base de datos de commits permanecerá intacta, solo el puntero de posición actual está configurado para commit actualmente seleccionado.

Quiero cambiar el estado de los archivos a una confirmación específica, ejecutar un proyecto y, cuando termine, restaurar los archivos a la última confirmación.

¿Cómo hacer esto sin comprimir toda la carpeta del proyecto?

Pablo
fuente

Respuestas:

344

Si está en una determinada rama mybranch, simplemente continúe y git checkout commit_hash. Luego puede regresar a su sucursal git checkout mybranch. Tuve el mismo juego que biseca un error hoy :) Además, debes saber sobre git bisect .

Alexander Pavlov
fuente
66
Tenga en cuenta que puede hacerlo git checkout commit_hashsi está en un repositorio limpio y no necesita hacer ramificaciones. Podría ser más fácil para algunos casos de uso (como el mío).
enderland
@enderland: tu HEAD siempre apunta a alguna rama, normalmente :)
Alexander Pavlov
Tuve un problema en el que tuve que usar todo el hash de confirmación porque no se aceptó uno parcial.
mightyiam
66
Votación a favor de la git bisectreferencia; ¡Qué herramienta extremadamente útil!
Niek
54

Primero, use git logpara ver el registro, elija la confirmación que desee, anote el hash sha1 que se utiliza para identificar la confirmación. A continuación, corre git checkout hash. Después de que haya terminado, git checkout original_branch. Esto tiene la ventaja de no mover el HEAD, simplemente cambia la copia de trabajo a un commit específico.

Femaref
fuente
44
Creo que te refieres git checkout <original_branch>. git checkout HEADes efectivamente un NOOP
Abe Voelker
3
git reset --hard <hash>cambia la CABEZA de la rama actual, mientras git checkout <hash>obtiene un pago separado que no cambia ninguna rama, y ​​puede regresar fácilmente sin conocer la identificación hash original de su rama como se muestra en esta respuesta.
jofel
Pregunta de principiante de @Femaref: dado el contexto de esta pregunta (cambiar temporalmente a una confirmación anterior), ¿por qué sería una ventaja o una desventaja mover o no mover la CABEZA?
loco sobre natty
@nuttyaboutnatty Suponiendo que mi edición esté aprobada, debería responder a su pregunta. HEAD en realidad se mueve en cualquier caso; pero en un pago, la referencia de rama a la que HEAD apunta no se mueve en sí misma.
echristopherson
15

Además de las otras respuestas aquí que le muestran cómo git checkout <the-hash-you-want>vale la pena saber que puede volver a donde estaba usando:

git checkout @{-1}

Esto suele ser más conveniente que:

git checkout what-was-that-original-branch-called-again-question-mark

Como puede anticipar, git checkout @{-2}lo llevará de regreso a la sucursal en la que se encontraba git checkouthace dos s, y de manera similar para otros números. Si puedes recordar dónde estabas para números más grandes, deberías obtener algún tipo de medalla por eso.


Lamentablemente para la productividad, git checkout @{1}no te lleva a la sucursal en la que estarás en el futuro, lo cual es una pena.

Benjohn
fuente
1
Tenga en cuenta que git checkout -es un alias abreviado paragit checkout @{-1}
Nathanael
@Nathanael OMGOD , de ninguna manera ... ¡esto lo cambia todo! ¡Bien gracias! ... Iba a incorporar esto en la respuesta, pero creo que también es útil saber acerca de la @{n}sintaxis general , ya que funciona con muchos comandos git. Me resultó difícil agregar su taquigrafía sin hacer que la respuesta fuera bastante confusa. En cambio, he votado tu comentario, espero que la gente lo vea. Gracias de nuevo.
Benjohn
1
No hay problema. Esta discusión es tangencial a la pregunta real de todos modos. Más de un bono! A menudo uso la misma sintaxis para fusionar características en una versión. por ejemplo, git merge -para fusionar la rama que había desprotegido por última vez en la rama desprotegida actualmente. Es como cd -en bash.
Nathanael