Comparteix a través de


Comprender la simplificación del historial de Git

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019

La simplificación del historial de Git puede llegar a ser una bestia desconcertante. El 99 % del tiempo que ni siquiera sabrá que existe, pero en ocasiones emergerá de un rincón oscuro de Git y le morderá. En este artículo, analizaremos qué es la simplificación del historial y cómo puede generarnos confusión al examinar el historial de archivos.

Comencemos con un escenario común:

  1. Envía un cambio en un archivo y, después, fusiona el cambio mediante combinación en la rama principal.
  2. Algunos de sus compañeros también fusiona sus cambios mediante combinación en la rama principal.
  3. Vuelve un poco más tarde y se da cuenta de que faltan los cambios.
  4. Buscando al culpable, consulta el historial de archivos y se fija en que... ¡sus cambios ni siquiera aparecen!

El historial de confirmaciones de Git es un árbol. A veces, el historial cronológico no es el mismo que el del árbol de archivos real. Esta situación se produce con más frecuencia cuando una confirmación de combinación revierte un archivo a su estado original. En ese caso, la vista de historial predeterminada no mostrará todos los cambios, ya que técnicamente el archivo no ha cambiado. En este escenario, Git se da cuenta de que puede simplificar el historial, y probablemente haya quitado del registro los "cambios" que está buscando.

A menos que ya le haya pasado, esto podría frustrarle, y se pregunte ¿dónde puñetas están mis cambios?

Simplificación del historial: activado de forma predeterminada

Al ejecutar el comando log en un archivo (git log file.txt), el historial se simplificará automáticamente de forma predeterminada, y casi con total seguridad se ocultarán algunas confirmaciones de la salida. Para obtener más información, vea la página de git-log.

Lo que acrecienta la confusión es que la simplificación del historial no sucede si simplemente ejecutamos git log, porque se ven todos los cambios, no hay nada que simplificar.

Para desactivar la simplificación del historial, hay que usar el modificador de línea de comandos --full-history.

Un ejemplo de simplificación del historial

Para comprender mejor cómo funciona la simplificación, crearemos nuestro propio ejemplo de simplificación del historial. En primer lugar, echemos un vistazo a un diagrama del historial que vamos a crear:

Ramas de Git

Como se ve, haremos lo siguiente:

  1. Cree un archivo.
  2. Agregar una línea a ese archivo en una rama (animals)
  3. Agregue una línea diferente a ese archivo en otra rama (fruit)
  4. Fusionar animals mediante combinación de vuelta en la rama principal
  5. Fusionar fruits mediante combinación de vuelta en la rama principal y seleccionar la copia completa del archivo de la rama fruits
  6. Consultar el historial del archivo

Git simplificará el historial por nosotros. El paso 5 es clave aquí. Hemos omitido todos los cambios de la rama animals. Git se dará cuenta de que nuestro archivo básicamente no ha cambiado entre el paso 1 y el paso 5, por lo que solo nos mostrará dos entradas del historial.

En primer lugar, crearemos el archivo y lo agregaremos a nuestro repositorio:

> cd sample
> git init
> echo "some content" > test.txt
> git add test.txt
> git commit -m "Initial commit"

Ahora decidimos anexar el texto "donkeys" al archivo en una rama animals:

> git checkout -b animals
> echo "donkeys" >> test.txt
> git commit -am "We have added an animal"

Mientras estamos experimentando, decidimos que quizás prefiramos ir con fruit en nuestro archivo, así que creamos una rama diferente y anexamos el texto "bananas" al final del archivo:

> git checkout main -b fruit
> echo "bananas" >> test.txt
> git commit -am "We have added a fruit"

Satisfechos con nuestros cambios, decidimos volver a fusionar nuestra rama animals mediante combinación en la rama principal:

> git checkout main
> git merge animals

Echemos un vistazo ahora al registro de nuestro archivo test.txt:

> git log test.txt
    
    commit 6b33d99b996c430a60c9552b79245d1aa8320339
        Date:   Mon Feb 15 10:45:33 2016 -0500

        We have added an animal

    commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
        Date:   Mon Feb 15 10:44:18 2016 -0500

        Initial commit

Por ahora todo bien, ¿no? No se ve nada fuera de lo normal en la salida del registro. Ahora, supongamos que cambiamos de opinión y decidimos fusionar la rama fruit mediante combinación:

>git merge fruit
    
    Auto-merging test.txt
    CONFLICT (content): Merge conflict in test.txt
    Automatic merge failed; fix conflicts and then commit the result.

Oh oh, ¡tenemos un conflicto de combinación! Tras analizarlo un poco, decidimos usar el archivotest.txt entero de nuestra rama fruit. Normalmente, usaríamos algún tipo de editor de texto o herramienta de combinación, pero bastará con volver a crear el archivo entero, ya que son solo dos líneas:

> echo "some content" > test.txt
> echo "bananas" >> test.txt
> git commit -am "Fixed merge conflict"

Echemos un vistazo ahora al historial de nuestro archivo test.txt:

> git log test.txt
    
    commit fdd4dfd816c4efebc5bdb240f49e934e299db581
        Date:   Mon Feb 15 10:51:06 2016 -0500

        We have added a fruit

    commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
        Date:   Mon Feb 15 10:44:18 2016 -0500

        Initial commit

Vale, no vemos ningún cambio de nuestro primer experimento en el registro... ¡ni tampoco nuestra fusión mediante combinación! ¿Siguen ahí? ¿Git eliminó los cambios por completo?

> git log --full-history test.txt

Como vemos, aunque ha simplificado el registro sin la marca full-history, Git ha conservado todos nuestros cambios:

> commit 5d0bb77a24e265dc154654fb3b5be331b53bf977
    Merge: 6b33d99 fdd4dfd
        Date:   Mon Feb 15 10:59:34 2016 -0500

        Fixed merge conflict

    commit fdd4dfd816c4efebc5bdb240f49e934e299db581
        Date:   Mon Feb 15 10:51:06 2016 -0500

        We have added a fruit

    commit 6b33d99b996c430a60c9552b79245d1aa8320339
        Date:   Mon Feb 15 10:45:33 2016 -0500

        We have added an animal

    commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
        Date:   Mon Feb 15 10:44:18 2016 -0500

        Initial commit

Resumen de simplificación del historial de Git

Lo que sucede con la simplificación del historial es que casi nunca lo percibimos, pero cuando se produce un conflicto de fusión mediante combinación y queremos saber lo que ha ocurrido, podemos acabar consultando el historial de registros de Git y preguntándonos dónde están los cambios.

Ahora, en lugar de entrar en pánico, ya sabemos que:

  • La simplificación del historial de archivos está activada de forma predeterminada.
  • La marca --full-history nos proporcionará un historial de archivos más completo.

Actualización: desde que redacté este artículo, Azure DevOps Services ha incorporado a la web algunas opciones de visualización del historial alucinantes. ¿Qué significa esto? Pues que, si no queremos iniciar sesión a través de la línea de comandos, simplemente podemos escoger el archivo cuyo historial queremos ver en nuestro explorador y aparecerá el siguiente filtro de historial, donde podemos especificar vistas de historial simples o no tan simples:

Filtros de Git

(c) 2016 Microsoft Corporation. Todos los derechos reservados. Este documento se proporciona "tal cual". La información y las opiniones expresadas en este documento, incluidas las direcciones URL y otras referencias a sitios web de Internet, pueden cambiar sin previo aviso. Usted asume el riesgo de utilizarla.

Este documento no le proporciona ningún derecho legal sobre ninguna propiedad intelectual de ningún producto de Microsoft. Puede copiar y usar este documento para su uso interno de referencia.