¿Cuál es la diferencia entre 'git reset --hard HEAD ~ 1' y 'git reset --soft HEAD ~ 1'?


Respuestas:


177

git resetconoce cinco "modos": suave, mixto, duro, fusionar y mantener. Comenzaré con los tres primeros, ya que estos son los modos que normalmente encontrarás. Después de eso, encontrarás una pequeña bonificación, así que estad atentos.

suave

Cuando lo use git reset --soft HEAD~1, eliminará la última confirmación de la rama actual, pero los cambios de archivo permanecerán en su árbol de trabajo . Además, los cambios permanecerán en su índice, por lo que seguir con un git commitcreará una confirmación con exactamente los mismos cambios que la confirmación que "eliminó" antes.

mezclado

Este es el modo predeterminado y bastante similar al suave. Cuando "elimine" una confirmación con git reset HEAD~1, todavía mantendrá los cambios en su árbol de trabajo pero no en el índice; así que si quieres "rehacer" la confirmación, tendrás que agregar los cambios ( git add) antes de realizar la confirmación.

difícil

Al usarlo git reset --hard HEAD~1, perderá todos los cambios no comprometidos además de los cambios introducidos en la última confirmación. Los cambios no permanecerán en su árbol de trabajo, por lo que hacer un git statuscomando le dirá que no tiene ningún cambio en su repositorio.

Pisa con cuidado con este. Si elimina accidentalmente los cambios no comprometidos que nunca fueron rastreados por git(hablar: comprometidos o al menos agregados al índice), no tiene forma de recuperarlos git.

Prima

mantener

git reset --keep HEAD~1es interesante y útil. Solo restablece los archivos que son diferentes entre el compromiso actual HEAD y el dado. Anula el restablecimiento si alguno de estos archivos tiene cambios no confirmados. Básicamente actúa como una versión más segura de hard.

Este modo es particularmente útil cuando tiene muchos cambios y desea cambiar a una rama diferente sin perder estos cambios, por ejemplo, cuando comenzó a trabajar en la rama incorrecta.


Puedes leer más sobre eso en la documentación de git reset .

Nota
Cuando se hace git resetpara eliminar una confirmación, la confirmación no se pierde realmente, simplemente no hay ninguna referencia que apunte a ella ni a sus hijos. Aún puede recuperar una confirmación que fue "eliminada" git resetencontrando su clave SHA-1, por ejemplo con un comando como git reflog.


1
No estoy de acuerdo con que estos 3 sean los que deberíamos utilizar habitualmente. Son los 3 que estuvieron disponibles por primera vez, así que la gente habla más de estos 3, pero --hardcasi nunca es lo correcto, ya que --keepes mucho más seguro y se aplica a la mayoría de los escenarios donde --hardfunciona. Entrenar los dedos para usar --keeppodría salvarlo, algún día ...
Matthieu Moy

No traté de sugerir que deberíamos usarlos, simplemente que son comandos que uno encuentra la mayor parte del tiempo. Siéntase libre de editar la respuesta como mejor le parezca.
Sascha Wolf

Para agregar un poco más de detalles, después de git reset --soft HEAD ~ 1, use git commit --reuse-message = HEAD @ {1} para reutilizar la última confirmación con el índice antiguo preservado como se muestra aquí stackoverflow.com/a/ 25930432/2883282
englealuze

3
@MatthieuMoy, tres años tarde, pero agregué una sección sobre keep. ;)
Sascha Wolf

¿Cómo puedo deshacer la última confirmación? Por favor ayuda. Si utilizo git reset --soft HEAD ~ 1, recibo: fatal: argumento ambiguo 'HEAD ~ 1': revisión desconocida o ruta que no está en el árbol de trabajo. Use '-' para separar rutas de revisiones, así: 'git <comando> [<revisión> ...] - [<archivo> ...]'
elvis

6

Git reset tiene 5 modos principales: suave, mixto, combinado, duro, mantener . La diferencia entre ellos es cambiar o no cambiar encabezado, etapa (índice), directorio de trabajo .

Git reset --hard cambiará el encabezado, el índice y el directorio de trabajo.
Git reset --soft solo cambiará de cabeza. Sin cambios en el índice, directorio de trabajo.

En otras palabras, si desea deshacer su compromiso, --soft debería ser lo suficientemente bueno. Pero después de eso, todavía tiene los cambios de una mala confirmación en su índice y directorio de trabajo. Puede modificar los archivos, arreglarlos, agregarlos al índice y confirmar nuevamente.

Con --hard, obtiene una pizarra limpia en su proyecto. Como si no hubiera habido ningún cambio desde la última confirmación. Si estás seguro de que esto es lo que quieres, sigue adelante. Pero una vez que hagas esto, perderás tu última confirmación por completo. (Nota: todavía hay formas de recuperar el compromiso perdido).


5

Este es un artículo útil que muestra gráficamente la explicación del comando de reinicio.

https://git-scm.com/docs/git-reset

Restablecer --hard puede ser bastante peligroso ya que sobrescribe su copia de trabajo sin verificar, por lo que si no ha enviado el archivo en absoluto, desaparecerá.

En cuanto al árbol de origen, no conozco ninguna forma de deshacer las confirmaciones. Lo más probable es que use restablecer debajo de las cubiertas de todos modos


+1 para el enlace a la documentación oficial. También mencionaría lo git reset --helpque explica bastante bien (en mi opinión) los cinco modos, o al menos los dos que pide el OP.
ThanksForAllTheFish

1
El enlace está roto. Probablemente esta sea la versión actual: git-scm.com/docs/git-reset
Kiki Jewell

1

Esta es la principal diferencia entre use git reset --hard y git reset --soft:

--soft

No toca el archivo de índice o el árbol de trabajo en absoluto (pero restablece el cabezal, como lo hacen todos los modos). Esto deja todos sus archivos modificados "Cambios por confirmar", como lo pondría git status.

--hard

Restablece el índice y el árbol de trabajo. Se descartan los cambios realizados en los archivos de seguimiento en el árbol de trabajo.


1
Esto es lo que estaba buscando. Sucinto y preciso.
Qasim
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.