Close

Resetting, checking out & reverting


The git reset, git checkout, and git revert commands are some of the most useful tools in your Git toolbox. They all let you undo some kind of change in your repository, and the first two commands can be used to manipulate either commits or individual files.

Como son muy similares, es muy fácil confundir qué comando se debe usar en una situación de desarrollo determinada. En este artículo, compararemos las configuraciones más comunes de git reset, git checkout y git revert. Espero que puedas marcharte con la seguridad necesaria para navegar por tu repositorio con cualquiera de estos comandos.

Los tres árboles de Git

It helps to think about each command in terms of their effect on the three state management mechanisms of a Git repository: the working directory, the staged snapshot, and the commit history. These components are sometimes known as "The three trees" of Git. We explore the three trees in depth on the git reset page. Keep these mechanisms in mind as you read through this article.

Una extracción es una operación que mueve el puntero de referencia HEAD a una confirmación especificada. Para hacer una demostración, vamos a analizar el siguiente ejemplo:

Mueve el puntero de referencia HEAD a una confirmación especificada
bases de datos
Material relacionado

Cómo mover un repositorio de Git completo

Logotipo de Bitbucket
VER LA SOLUCIÓN

Aprende a usar Git con Bitbucket Cloud

En este ejemplo se muestra una secuencia de confirmaciones en la rama main. La referencia HEAD y la referencia de la rama main en estos momentos apuntan a la confirmación d. Ahora vamos a ejecutar git checkout b

Sequence of commits on the main branch

Esta es una actualización del árbol "Historial de confirmaciones". El comando git checkout se puede usar en un alcance de confirmación o de nivel de archivo. Una extracción de nivel de archivo cambiará el contenido del archivo por el de la confirmación específica.

Una reversión es una operación que toma una confirmación especificada y crea una nueva confirmación que invierte dicha confirmación especificada. git revert solo se puede ejecutar en un alcance de nivel de confirmación y no tiene funcionalidad de nivel de archivo.

El restablecimiento es una operación que toma una confirmación especificada y restablece los" tres árboles" para que coincidan con el estado del repositorio en esa confirmación especificada. El restablecimiento se puede invocar de tres maneras diferentes que corresponden a los tres árboles.

La extracción y el restablecimiento se utilizan generalmente para hacer operaciones de "deshacer" locales o privadas. Modifican el historial de un repositorio que puede provocar conflictos al ejecutar operaciones de envío a repositorios compartidos remotos. La reversión se considera una operación segura para "acciones de deshacer públicas", ya que crea un nuevo historial que se puede compartir de forma remota y no sobrescribe el historial del que pueden depender los miembros del equipo remoto.

Git reset vs revert vs checkout reference


En la siguiente tabla se resumen los casos de uso más comunes para todos estos comandos. Ten esta referencia a mano, ya que sin duda necesitarás usar al menos algunos de ellos durante tu trayectoria con Git.

Comando

Ámbito de aplicación

Casos de uso comunes

git reset

Ámbito de aplicación

Nivel de confirmación

Casos de uso comunes

Discard commits in a private branch or throw away uncommitted changes

git reset

Ámbito de aplicación

Nivel de archivo

Casos de uso comunes

Deshacer la preparación de un archivo

git checkout

Ámbito de aplicación

Nivel de confirmación

Casos de uso comunes

Cambiar entre ramas o inspeccionar instantáneas antiguas

git checkout

Ámbito de aplicación

Nivel de archivo

Casos de uso comunes

Descartar los cambios en el directorio de trabajo

git revert

Ámbito de aplicación

Nivel de confirmación

Casos de uso comunes

Deshacer confirmaciones en una rama pública

git revert

Ámbito de aplicación

Nivel de archivo

Casos de uso comunes

(N/D)

Commit level operations


Los parámetros que pasas a git reset y git checkout determinan su alcance. Cuando no incluyes una ruta de archivo como parámetro, funcionan en confirmaciones completas. Eso es lo que exploraremos en esta sección. Ten en cuenta que git revert no tiene un equivalente de nivel de archivo.

Reset a specific commit

En el nivel de confirmación, el restablecimiento es una forma de mover la punta de una rama a una confirmación diferente. Se puede usar para eliminar confirmaciones de la rama actual. Por ejemplo, el siguiente comando mueve la rama de revisión hacia atrás mediante dos confirmaciones.

git checkout hotfix git reset HEAD~2

Las dos confirmaciones que estaban al final de la revisión ahora son confirmaciones suspendidas o huérfanas. Esto significa que se eliminarán la próxima vez que Git realice una recolección de basura. En otras palabras, estás diciendo que quieres desecharlas. Esto se puede visualizar de la siguiente manera:

Restablecimiento de la rama de corrección en HEAD-2

Este uso de git reset es una forma sencilla de deshacer los cambios que no se han compartido con nadie más. Es el comando preferido si has empezado a trabajar en una función y de repente piensas: "¡Madre mía!, ¿qué estoy haciendo? Debería empezar de nuevo".

Además de mover la rama actual, también puedes hacer que git reset modifique la instantánea preparada o el directorio de trabajo pasándole una de las siguientes marcas:

  • —--soft: la instantánea preparada y el directorio de trabajo no se modifican de ninguna manera.
  • —mixed: la instantánea preparada se actualiza para que coincida con la confirmación especificada, pero el directorio de trabajo no se ve afectado. Esta es la opción predeterminada.
  • —hard: la instantánea preparada y el directorio de trabajo se actualizan para que coincidan con la confirmación especificada.

It’s easier to think of these modes as defining the scope of a git reset operation. For further detailed information visit the git reset page.

Extraer confirmaciones anteriores

El comando git checkout se usa para actualizar el estado del repositorio a un punto específico del historial de proyectos. Cuando se transmite con un nombre de rama, permite cambiar entre ramas.

git checkout hotfix

Internamente, todo lo que hace el comando anterior es mover HEAD a una rama diferente y actualizar el directorio de trabajo para que coincida. Como esto tiene el potencial de sobrescribir los cambios locales, Git te obliga a confirmar o guardar cualquier cambio en el directorio de trabajo que se perderá durante la operación de extracción. A diferencia de git reset, git checkout no mueve ninguna rama.

Moving HEAD from main to hotfix

También puedes extraer las confirmaciones arbitrarias pasando la referencia de confirmación en lugar de una rama. Esta operación hace exactamente lo mismo que cuando se extrae una rama: mueve la referencia HEAD a la confirmación especificada. Por ejemplo, el siguiente comando extraerá el elemento principal de la confirmación actual:

git checkout HEAD~2
Mover "HEAD" a una confirmación arbitraria

Esto resulta útil para inspeccionar rápidamente una versión anterior del proyecto. Sin embargo, dado que no hay una referencia de rama al HEAD actual, esto te pone en un estado HEAD separado. Esto puede ser peligroso si empiezas a añadir nuevas confirmaciones, porque no habrá forma de volver a ellas después de cambiar a otra rama. Por esta razón, siempre debes crear una nueva rama antes de agregar confirmaciones a un HEAD separado.

Undo public commits with revert

La reversión deshace una confirmación creando una nueva confirmación. Esta es una forma segura de deshacer los cambios, ya que no hay posibilidad de que se sobrescriba el historial de confirmaciones. Por ejemplo, el siguiente comando determinará los cambios incluidos en la penúltima confirmación, creará una nueva confirmación para deshacerlos y añadirá la nueva confirmación al proyecto existente.

git checkout hotfix git revert HEAD~2

Esto se puede visualizar de la siguiente manera:

Revertir la penúltima confirmación

Contrasta esto con git reset, que modifica el historial de confirmaciones existente. Por este motivo, git revert se debe usar para deshacer los cambios en una rama pública, mientras que git reset se debe reservar para deshacer los cambios en una rama privada.

También puedes pensar en git revert como una herramienta para deshacer cambios confirmados, mientras que git reset HEAD es para deshacer cambios no confirmados.

Al igual que git checkout, git revert tiene el potencial de sobrescribir archivos en el directorio de trabajo, por lo que te pedirá que confirmes o guardes los cambios que se perderían durante la operación de reversión.

File-level operations


Los comandos git reset y git checkout también aceptan una ruta de archivo opcional como parámetro. Esto modifica considerablemente su comportamiento. En lugar de operar en instantáneas completas, esto los obliga a limitar sus operaciones a un solo archivo.

Git reset a specific file

Cuando se invoca con una ruta de archivo, git reset actualiza la instantánea preparada para que coincida con la versión de la confirmación especificada. Por ejemplo, este comando buscará la versión de foo.py en la penúltima confirmación y la preparará para la próxima confirmación:

git reset HEAD~2 foo.py

Al igual que con la versión de git reset de nivel de confirmación, este se usa más habitualmente con HEAD en lugar de con una confirmación arbitraria. La ejecución de git reset HEAD foo.py deshará la preparación de foo.py. Los cambios que contiene seguirán presentes en el directorio de trabajo.

Mover un archivo del historial de confirmaciones a la instantánea preparada

Las marcas --soft, --mixed y --hard no tienen ningún efecto en la versión de nivel de archivo de git reset, ya que la instantánea preparada siempre se actualiza y el directorio de trabajo no lo hace nunca.

Git checkout file

Extraer un archivo es similar a usar git reset con una ruta de archivo, salvo que se actualiza el directorio de trabajo en lugar del entorno de ensayo. A diferencia de la versión de nivel de confirmación de este comando, este no mueve la referencia HEAD, lo que significa que no cambiarás de rama.

Mover un archivo del historial de confirmaciones al directorio de trabajo

Por ejemplo, el siguiente comando hace que foo.py en el directorio de trabajo coincida con el de la penúltima confirmación:

git checkout HEAD~2 foo.py

Al igual que la invocación de nivel de confirmación de git checkout, se puede usar para inspeccionar versiones anteriores de un proyecto, pero el alcance se limita al archivo especificado.

Si preparas y confirmas el archivo extraído, la operación tiene el efecto de "revertir" a la versión anterior de ese archivo. Ten en cuenta que esto elimina todos los cambios posteriores en el archivo, mientras que el comando git revert deshace solo los cambios introducidos por la confirmación especificada.

Al igual que git reset, esto se usa habitualmente con HEAD como referencia de confirmación. Por ejemplo, git checkout HEAD foo.py tiene el efecto de descartar los cambios no preparados en foo.py. Este es un comportamiento similar al de git reset HEAD --hard, pero solo actúa en el archivo especificado.

Resumen


You should now have all the tools you could ever need to undo changes in a Git repository. The git reset, git checkout, and git revert commands can be confusing, but when you think about their effects on the working directory, staged snapshot, and commit history, it should be easier to discern which command fits the development task at hand.


Compartir este artículo
Tema siguiente

Lecturas recomendadas

Consulta estos recursos para conocer los tipos de equipos de DevOps o para estar al tanto de las novedades sobre DevOps en Atlassian.

Gente que colabora utilizando un muro lleno de herramientas

Blog de Bitbucket

Ilustración de Devops

Ruta de aprendizaje de DevOps

Demostraciones de funciones con expertos de Atlassian del Centro de demostraciones

Cómo funciona Bitbucket Cloud con Atlassian Open DevOps

Suscríbete para recibir el boletín de DevOps

Thank you for signing up