¿Cuál es la diferencia entre git reset --mixed, --soft y --hard?

Resuelto Michael Chinen asked hace 14 años • 18 respuestas

Estoy buscando dividir una confirmación y no estoy seguro de qué opción de reinicio usar.

Estaba mirando la página En inglés sencillo, ¿qué hace "git reset"? , pero me di cuenta de que realmente no entiendo qué es el índice de git o el área de preparación y, por lo tanto, las explicaciones no ayudaron.

Además, los casos de uso de --mixedy --softme parecen iguales en esa respuesta (cuando desea corregir y volver a confirmar). ¿Alguien puede desglosarlo aún más? Me doy cuenta de que --mixedprobablemente sea la opción a seguir, pero quiero saber por qué . Por último, ¿qué pasa --hard?

¿Alguien puede darme un ejemplo de flujo de trabajo de cómo se seleccionarían las 3 opciones?

Michael Chinen avatar Aug 20 '10 11:08 Michael Chinen
Aceptado

Cuando modifica un archivo en su repositorio, el cambio inicialmente no se realiza. Para confirmarlo, debe prepararlo (es decir, agregarlo al índice) usando git add. Cuando realiza una confirmación, los cambios que se confirman son aquellos que se han agregado al índice.

git resetcambia, como mínimo, hacia dónde HEADapunta la rama actual ( ). La diferencia entre --mixedy --softes si su índice también se modifica o no. Entonces, si estamos en rama mastercon esta serie de confirmaciones:

- A - B - C (master)

HEADapunta Cy el índice coincide C.

Cuando ejecutamos git reset --soft B, master(y por lo tanto HEAD) ahora apunta a B, pero el índice todavía tiene los cambios de C; git statusLos mostraremos en escena. Entonces, si ejecutamos git commiten este punto, obtendremos una nueva confirmación con los mismos cambios que C.


Bien, empezando desde aquí de nuevo:

- A - B - C (master)

Ahora hagámoslo git reset --mixed B. (Nota: --mixedes la opción predeterminada). Una vez más, masterseñale HEADB, pero esta vez el índice también se modifica para que coincida B. Si ejecutamos git commiten este punto no pasará nada ya que el índice coincide HEAD. Todavía tenemos los cambios en el directorio de trabajo, pero como no están en el índice, git statuslos muestra como no preparados. Para cometerlos, deberías git addhacerlo como de costumbre.


Y finalmente, --hardes lo mismo que --mixed(cambia tu HEADíndice), excepto que --hardtambién modifica tu directorio de trabajo. Si estamos en Cy ejecutamos git reset --hard B, los cambios agregados en C, así como cualquier cambio no confirmado que tenga, se eliminarán y los archivos en su copia de trabajo coincidirán con commit B. Dado que de esta manera puede perder cambios permanentemente, siempre debe ejecutar git statusantes de realizar un restablecimiento completo para asegurarse de que su directorio de trabajo esté limpio o que esté de acuerdo con perder los cambios no confirmados.


Y finalmente, una visualización: ingrese la descripción de la imagen aquí

mkarasek avatar Aug 20 '2010 05:08 mkarasek

En los términos más simples:

  • --soft: cancelar la confirmación de los cambios, los cambios se dejan preparados ( índice ).
  • --mixed (predeterminado) : cancelar la confirmación + cambios sin preparar, los cambios se dejan en el árbol de trabajo .
  • --hard: cancelar la confirmación + cancelar la etapa + eliminar cambios, no queda nada.
Mo Ali avatar Apr 25 '2018 12:04 Mo Ali

Tres tipos de arrepentimiento

Muchas de las respuestas existentes no parecen responder a la pregunta real. Se trata de lo que hacen los comandos, no de lo que usted (el usuario) desea: el caso de uso . ¡Pero eso es lo que preguntó el OP!

Podría ser más útil formular la descripción en términos de qué es precisamente de lo que te arrepientes en el momento de dar una git resetorden. Digamos que tenemos esto:

A - B - C - D <- HEAD

Aquí hay algunos posibles arrepentimientos y qué hacer al respecto:

1. Lamento que B, C y D no sean un solo compromiso.

git reset --soft A. Ahora puedo confirmar inmediatamente y listo, todos los cambios desde A son una confirmación.

2. Lamento que B, C y D no sean dos confirmaciones (o diez confirmaciones, o lo que sea).

git reset --mixed A. Las confirmaciones desaparecieron y el índice volvió a A, pero el área de trabajo todavía se ve como tenía después de D. Así que ahora puedo agregar y confirmar en una agrupación completamente diferente.

3. Lamento que B, C y D hayan ocurrido en esta rama ; Ojalá me hubiera bifurcado después de A y hubieran sucedido en esa otra rama.

Haga una nueva rama otherbranchy luego git reset --hard A. La rama actual ahora termina en A, otherbranchsaliendo de ella y conteniendo B, C y D.

(Por supuesto, también podrías usar un restablecimiento completo porque desearías que B, C y D nunca hubieran sucedido).

matt avatar Jan 10 '2020 03:01 matt

Tenga en cuenta que esta es una explicación simplificada que pretende ser un primer paso para intentar comprender esta compleja funcionalidad.

Puede resultar útil para los estudiantes visuales que quieran visualizar cómo se ve el estado de su proyecto después de cada uno de estos comandos:

Dado:- A - B - C (master)


Para aquellos que usan Terminal con el color activado (git config --global color.ui auto):

git reset --soft Ay verás las cosas de B y C en verde (preparadas y listas para enviarse)

git reset --mixed A(o git reset A) y verá el material de B y C en rojo (sin preparar y listo para ser preparado (verde) y luego comprometido)

git reset --hard Ay ya no verás los cambios de B y C por ningún lado (será como si nunca hubieran existido)


O para aquellos que usan un programa GUI como 'Tower' o 'SourceTree'

git reset --soft Ay verás el material de B y C en el área de 'archivos preparados' listos para confirmar

git reset --mixed A(o git reset A) y verá el material de B y C en el área de 'archivos no preparados' listos para ser movidos a preparados y luego confirmados.

git reset --hard Ay ya no verás los cambios de B y C por ningún lado (será como si nunca hubieran existido)

timhc22 avatar Nov 21 '2014 12:11 timhc22

Todas las demás respuestas son geniales, pero creo que es mejor comprenderlas dividiendo los archivos en tres categorías: unstaged, staged, commit:

  • --harddebe ser fácil de entender, restaura todo
  • --mixed (por defecto) :
    1. unstagedarchivos: no cambiar
    2. stagedarchivos: mover aunstaged
    3. commitarchivos: mover aunstaged
  • --soft:
    1. unstagedarchivos: no cambiar
    2. stagedarchivos: no cambiar
    3. commitarchivos: mover astaged

En resumen:

  • --softLa opción moverá todo (excepto unstagedlos archivos) astaging area
  • --mixedLa opción moverá todo aunstaged area
Hansen W avatar Jun 14 '2019 23:06 Hansen W