¿Cuál es la diferencia entre "git reset" y "git checkout"?

Resuelto prosseek asked hace 14 años • 8 respuestas

Siempre he pensado en git resety git checkoutcomo lo mismo, en el sentido de que ambos devuelven el proyecto a un compromiso específico. Sin embargo, creo que no pueden ser exactamente iguales, ya que sería redundante. ¿Cuál es la diferencia real entre los dos? Estoy un poco confundido, ya que svn solo tiene svn coque revertir la confirmación.

AGREGADO

VonC y Charles explicaron muy bien las diferencias entre git resety . git checkoutMi comprensión actual es que git resetrevierte todos los cambios a una confirmación específica, mientras que git checkoutmás o menos se prepara para una rama. Los siguientes dos diagramas me parecieron bastante útiles para llegar a este entendimiento:

http://a.imageshack.us/img651/1559/86421927.png http://a.imageshack.us/img801/1986/resetr.png

AGREGADO 3

Desde http://think-like-a-git.net/sections/rebase-from-the-ground-up/using-git-cherry-pick-to-simulate-git-rebase.html , el pago y el restablecimiento pueden emular la rebase.

ingrese la descripción de la imagen aquí

git checkout bar 
git reset --hard newbar 
git branch -d newbar 

ingrese la descripción de la imagen aquí

prosseek avatar Sep 04 '10 03:09 prosseek
Aceptado
  • git resetSe trata específicamente de actualizar el índice , mover el HEAD.
  • git checkoutse trata de actualizar el árbol de trabajo (al índice o al árbol especificado). Actualizará el HEAD solo si realiza el pago en una sucursal (de lo contrario, terminará con un HEAD separado ).
    (En realidad, con Git 2.23 Q3 2019, esto será git restore, no necesariamente git checkout)

En comparación, dado que svn no tiene índice, solo un árbol de trabajo, svn checkoutcopiará una revisión determinada en un directorio separado.
El equivalente más cercano para git checkoutsería:

  • svn update(si estás en la misma rama, es decir, la misma URL SVN)
  • svn switch(si realiza el pago, por ejemplo, en la misma sucursal, pero desde otra URL del repositorio SVN)

Todas esas tres modificaciones del árbol de trabajo ( ,, svn checkout) tienen un solo comando en git :. Pero como git también tiene la noción de índice (esa "área de preparación" entre el repositorio y el árbol de trabajo), también tienes .updateswitchgit checkout
git reset


Thinkeye menciona en los comentarios el artículo " Reset Demystified ".

Por ejemplo, si tenemos dos ramas, ' master' y ' develop' que apuntan a confirmaciones diferentes, y actualmente estamos en ' develop' (por lo que HEAD apunta a ella) y ejecutamos git reset master, ' develop' ahora apuntará a la misma confirmación que ' master' hace.

Por otro lado, si en lugar de eso ejecutamos git checkout master, ' develop' no se moverá, HEADél mismo lo hará. HEADahora apuntará a ' master'.

Entonces, en ambos casos vamos a apuntar HEADa confirmar A, pero la forma de hacerlo es muy diferente. resetmoverá los HEADpuntos de la rama, el pago HEADse mueve para apuntar a otra rama.

http://git-scm.com/images/reset/reset-checkout.png

Sin embargo, sobre esos puntos:

LarsH agrega en los comentarios :

Sin embargo, el primer párrafo de esta respuesta es engañoso: " git checkout... actualizará el HEAD sólo si paga una rama (si no, terminará con un HEAD separado)".
No es cierto: git checkoutactualizará el HEAD incluso si verifica una confirmación que no es una rama (y sí, termina con un HEAD separado, pero aún así se actualizó).

git checkout a839e8f updates HEAD to point to commit a839e8f.

De Novo coincide en los comentarios :

@LarsH tiene razón.
La segunda viñeta tiene una idea errónea sobre en qué se encuentra HEAD y actualizará HEAD solo si compra una sucursal.
HEAD va donde quiera que estés, como una sombra.
Al extraer alguna referencia que no sea una rama (por ejemplo, una etiqueta), o una confirmación directamente, se moverá HEAD. La cabeza separada no significa que se haya separado de la CABEZA, significa que la cabeza está separada de una rama ref, desde la cual puede ver, por ejemplo, git log --pretty=format:"%d" -1.

  • Los estados principales adjuntos comenzarán con (HEAD ->,
  • detached seguirá mostrándose (HEAD, pero no tendrá una flecha hacia una referencia de rama.
VonC avatar Sep 03 '2010 20:09 VonC

En su forma más simple, resetrestablece el índice sin tocar el árbol de trabajo, mientras checkoutcambia el árbol de trabajo sin tocar el índice.

Restablece el índice para que coincida HEAD, el árbol de trabajo se deja solo:

git reset

Conceptualmente, esto verifica el índice en el árbol de trabajo. Para que realmente haga algo, tendría que usar -fpara forzarlo a sobrescribir cualquier cambio local. Esta es una característica de seguridad para garantizar que el formulario "sin argumentos" no sea destructivo:

git checkout

Una vez que comienzas a agregar parámetros, es cierto que hay cierta superposición.

checkoutGeneralmente se usa con una rama, etiqueta o confirmación. En este caso, se restablecerá HEADel índice de la confirmación dada y también se realizará la extracción del índice en el árbol de trabajo.

Además, si lo proporciona, --hardpuede resetsolicitar resetsobrescribir el árbol de trabajo y restablecer el índice.

Si actualmente tiene una sucursal registrada, existe una diferencia crucial entre resety checkoutcuándo proporciona una sucursal alternativa o se compromete. resetcambiará la rama actual para que apunte a la confirmación seleccionada, mientras que checkoutdejará la rama actual sola pero verificará la rama proporcionada o confirmará en su lugar.

Otras formas de resete commitimplican el suministro de caminos.

Si proporciona rutas, resetno podrá proporcionarlas --hardy resetsolo cambiará la versión de índice de las rutas proporcionadas a la versión en la confirmación proporcionada (o HEADsi no especifica una confirmación).

Si proporciona rutas a checkout, resetactualizará la versión de índice de las rutas proporcionadas para que coincida con la confirmación proporcionada (o HEAD), pero siempre verificará la versión de índice de las rutas proporcionadas en el árbol de trabajo.

CB Bailey avatar Sep 03 '2010 20:09 CB Bailey

Un caso de uso simple al revertir un cambio:
1. Utilice restablecer si desea deshacer la preparación de un archivo modificado.
2. Utilice la opción de pago si desea descartar cambios en archivos no preparados.

John Doe avatar Jan 28 '2016 02:01 John Doe

La diferencia clave en pocas palabras es que reset mueve la referencia de rama actual , mientras que checkoutno lo hace (mueve HEAD).

Como explica el libro Pro Git en Reset Demystified ,

Lo primero que resetharemos será mover aquello a lo que apunta HEAD . Esto no es lo mismo que cambiar el propio HEAD (que es lo que checkouthace); reset mueve la rama a la que apunta HEAD. Esto significa que si HEAD está configurado en la masterrama (es decir, actualmente estás en la masterrama), la ejecución git reset 9e5e6a4comenzará masterseñalando 9e5e6a4. [énfasis añadido]

Consulte también la respuesta de VonC para obtener un texto muy útil y un extracto de diagrama del mismo artículo, que no duplicaré aquí.

Por supuesto, hay muchos más detalles sobre los efectos checkoutque resetpuede tener en el índice y el árbol de trabajo, dependiendo de los parámetros que se utilicen. Puede haber muchas similitudes y diferencias entre los dos comandos. Pero a mi modo de ver, la diferencia más crucial es si mueven la punta de la rama actual.

LarsH avatar Feb 20 '2018 18:02 LarsH