¿Cuál es la diferencia entre Git Revert, Checkout y Reset?

274

Estoy tratando de aprender cómo restaurar o archivos y proyectos de reversión a un estado anterior, y no entienden la diferencia entre git revert, checkouty reset. ¿Por qué hay 3 comandos diferentes para aparentemente el mismo propósito, y cuándo alguien debería elegir uno sobre el otro?

Haziz
fuente

Respuestas:

461

Estos tres comandos tienen propósitos completamente diferentes. Ni siquiera son remotamente similares.

git revert

Este comando crea una nueva confirmación que deshace los cambios de una confirmación anterior. Este comando agrega un nuevo historial al proyecto (no modifica el historial existente).

git checkout

Este comando extrae el contenido del repositorio y lo coloca en su árbol de trabajo. También puede tener otros efectos, dependiendo de cómo se invocó el comando. Por ejemplo, también puede cambiar en qué rama está trabajando actualmente. Este comando no realiza ningún cambio en el historial.

git reset

Este comando es un poco más complicado. Realmente hace un par de cosas diferentes dependiendo de cómo se invoque. Modifica el índice (el llamado "área de ensayo"). O cambia a qué compromiso apunta una cabeza de rama actualmente. Este comando puede alterar el historial existente (cambiando el compromiso al que hace referencia una rama).

Usando estos comandos

Si se ha realizado una confirmación en algún lugar de la historia del proyecto, y luego decide que la confirmación es incorrecta y no debería haberse realizado, entonces esa git revertes la herramienta para el trabajo. Deshacerá los cambios introducidos por la mala confirmación, registrando el "deshacer" en la historia.

Si ha modificado un archivo en su árbol de trabajo, pero no ha confirmado el cambio, puede utilizar git checkoutpara retirar una copia del archivo recién salido del repositorio.

Si ha realizado un compromiso, pero no lo ha compartido con nadie más y decide que no lo quiere, puede usarlo git resetpara reescribir el historial para que parezca que nunca lo hizo.

Estos son solo algunos de los posibles escenarios de uso. Hay otros comandos que pueden ser útiles en algunas situaciones, y los tres comandos anteriores también tienen otros usos.

Dan Molding
fuente
13
Por lo tanto, los tres comandos se pueden usar para DESHACER algo de trabajo, lo que significa que no son tan "completamente diferentes". Mismo concepto, diferentes contextos.
Bruno Santos
16
@BrunoSantos: Candelabros, tubos de plomo, dagas y cuerdas se pueden usar para asesinar personas, pero eso no significa que ninguna de esas cosas sea particularmente similar.
Dan Molding
12
@ Dan Mounlding - En realidad, hay muchos casos en que git resety git checkoutpuede hacer exactamente lo mismo. Decir que "ni siquiera son remotamente similares" no es solo una exageración excesiva: ni siquiera es remotamente cierto. Estos dos comandos pueden hacer muchas cosas diferentes, algunas de las cuales se superponen por completo. Ejemplo: git reset --hardy git checkout -- .haremos exactamente lo mismo. Y lógicamente hablando, git reset --hard <path>y git checkout <path>también debería hacer exactamente lo mismo: git, sin embargo, te impide hacerlo. Confundir estos dos comandos es MUY fácil.
DanGordon
55
@DanGordon Me doy cuenta de que probablemente tendremos una diferencia de opinión aquí. Sin embargo, creo que debería dar alguna explicación. No puede hacer lo git reset --hard <path>que puede git checkout <path>precisamente porque los dos comandos hacen algo completamente diferente. git resetle dice a Git que mueva HEAD a un commit diferente. git checkoutPor otro lado, no le pide a Git que haga nada con HEAD. Deja a HEAD solo y simplemente revisa un archivo. Sí, puedes crearlos de tal manera que tengan efectos similares. Pero lo que realmente hacen es totalmente diferente.
Dan Molding el
46

Digamos que has cometido:

C
B
A

git revert B, creará una confirmación que deshace los cambios en B.

git revert A, creará una confirmación que deshace los cambios A, pero no toca los cambios enB

Tenga en cuenta que si los cambios en Bdependen de los cambios en A, la reversión de Ano es posible.

git reset --soft A, cambiará el historial de confirmación y el repositorio; El directorio provisional y de trabajo seguirá estando en estado de C.

git reset --mixed A, cambiará el historial de confirmación, el repositorio y la preparación; el directorio de trabajo seguirá en estado de C.

git reset --hard A, cambiará el historial de confirmaciones, el repositorio, la preparación y el directorio de trabajo; volverás al estado de Acompletamente.

Akavall
fuente
1
Así que la respuesta intuitiva .. ¿qué hay de la caja
MJ Studio
29
  • git revertse usa para deshacer una confirmación previa. En git, no puedes alterar o borrar una confirmación anterior. (En realidad puede, pero puede causar problemas). Entonces, en lugar de editar el commit anterior, revert introduce un nuevo commit que revierte uno anterior.
  • git reset se utiliza para deshacer cambios en su directorio de trabajo que aún no se han iniciado.
  • git checkoutse usa para copiar un archivo de algún otro commit a su árbol de trabajo actual. No confirma automáticamente el archivo.
Jonathan
fuente
77
Creo que estás equivocado acerca de "git reset". "git reset" restablece su HEAD a una de las confirmaciones anteriores, no restablece su directorio de trabajo. El directorio de trabajo se "restablece" mediante "git checkout [nombre de archivo]"
luigi7up
11
git reset --softrestablece el HEAD solamente, git reset --hardrestablece el HEAD y su directorio de trabajo.
Ehryk
git reset --mixed (predeterminado): sin confirmar + cambios en el
escenario
21
  • git checkout modifica tu árbol de trabajo,
  • git reset modifica a qué referencia apunta la rama en la que estás,
  • git revert agrega una confirmación de deshacer cambios.
dan_waterworth
fuente
44
git reset no solo modifica la confirmación a la que apunta una rama , sino que también se utiliza para eliminar los archivos del índice y puede modificar la copia de trabajo con git reset --mixed(el valor predeterminado).
git reset --soft: cambios no confirmados, los cambios se dejan en escena (índice). git reset --mixed (predeterminado): sin confirmar + cambios en el escenario, los cambios se dejan en el árbol de trabajo. git reset --hard: descommitir + unstage + eliminar cambios, no queda nada.
NattyC
6

Restablecer: en el nivel de confirmación, restablecer es una forma de mover la punta de una rama a una confirmación diferente. Esto se puede usar para eliminar confirmaciones de la rama actual.

Revertir: revertir deshace una confirmación creando una nueva confirmación. Esta es una forma segura de deshacer cambios, ya que no tiene posibilidad de volver a escribir el historial de confirmación. Compare esto con git reset, que altera el historial de confirmación existente. Por esta razón, git revert debe usarse para deshacer cambios en una rama pública, y git reset debe reservarse para deshacer cambios en una rama privada.

Puede echar un vistazo en este enlace: restablecer, pagar y revertir

Sachchidanand Singh
fuente