3  Clase: Resolución de conflictos en Git

Introducción

En esta clase aprenderemos:

  • El origen de los conflictos en Git: Por qué se producen y en qué casos Git no puede fusionar automáticamente los cambios.
  • Cómo generar un conflicto de manera controlada: Modificando el mismo bloque de código en dos ramas diferentes.
  • La resolución manual de conflictos: Identificando los marcadores de conflicto y decidiendo qué cambios conservar.

Supondremos que nuestro repositorio cuenta con dos ramas: main y arregla_paquetes. En el estado inicial ambas ramas están sincronizadas y el archivo main.py en la rama main tiene el siguiente contenido:

# %% 
import pandas as pd
import numpy as np

# %%
f = "./data/datos.txt"
f = "./data/datos.txt" #nueva linea  

pd.read_csv(f)
# %%

1. Preparar el Escenario

Antes de comenzar, asegúrate de que tu repositorio tiene las dos ramas y que ambas están actualizadas. Puedes comprobarlo con:

# Mostrar ramas locales
git branch

# Si es necesario, actualizar ambas ramas:
git checkout main
git pull

git checkout arregla_paquetes
git pull

2. Generar el Conflicto

Para crear un conflicto, modificaremos la misma línea en el archivo main.py en cada rama.

2.1. Modificar la Rama main

  1. Cambia a la rama main:

    git checkout main
  2. Abre el archivo main.py en tu editor de texto y localiza la siguiente sección:

    f = "./data/datos.txt"
    f = "./data/datos.txt" #nueva linea  
  3. Modifica la segunda línea para que se vea así (por ejemplo, actualizando el comentario):

    f = "./data/datos.txt"
    f = "./data/datos.txt" #nueva linea actualizada en main
  4. Guarda el archivo y realiza el commit:

    git add main.py
    git commit -m "Actualiza línea en main: nueva linea actualizada en main"

2.2. Modificar la Rama arregla_paquetes

  1. Cambia a la rama arregla_paquetes:

    git checkout arregla_paquetes
  2. Abre el archivo main.py y modifica la misma línea de la siguiente forma:

    f = "./data/datos.txt"
    f = "./data/archivo_modificado.txt" # corregido en arregla_paquetes
  3. Guarda el archivo y realiza el commit:

    git add main.py
    git commit -m "Corrige ruta en arregla_paquetes: cambia a archivo_modificado.txt"

Nota: Como hemos modificado la misma línea en ambas ramas de forma diferente, al intentar fusionarlas se producirá un conflicto.

3. Fusionar Ramas y Ver el Conflicto

Ahora intentaremos fusionar la rama arregla_paquetes en main.

  1. Cambia a la rama main:

    git checkout main
  2. Inicia el merge:

    git merge arregla_paquetes

Al ejecutar el comando anterior, Git detectará que la misma parte del archivo main.py ha sido modificada de forma diferente en cada rama y detendrá el proceso de fusión, mostrando un mensaje de conflicto. Verás algo similar a lo siguiente en la terminal:

Auto-merging main.py
CONFLICT (content): Merge conflict in main.py
Automatic merge failed; fix conflicts and then commit the result.

4. Analizar y Resolver el Conflicto

Abre el archivo main.py. Encontrarás los marcadores de conflicto que Git ha insertado para señalar las diferencias. La sección conflictiva se verá de la siguiente manera:

f = "./data/datos.txt"
<<<<<<< HEAD
f = "./data/datos.txt" #nueva linea actualizada en main
=======
f = "./data/archivo_modificado.txt" # corregido en arregla_paquetes
>>>>>>> arregla_paquetes

Explicación de los marcadores:

  • <<<<<<< HEAD: Indica el comienzo de la sección que proviene de la rama actual (en este caso, main).
  • La parte que sigue hasta ======= corresponde al contenido de main.
  • =======: Separa los cambios de ambas ramas.
  • La sección entre ======= y >>>>>>> arregla_paquetes corresponde al contenido de la rama arregla_paquetes.
  • >>>>>>> arregla_paquetes: Indica el final del conflicto, señalando la rama con la otra versión.

4.1. Decidir la Solución

Debes decidir cuál es la versión correcta o si se requiere una combinación de ambas. Por ejemplo:

  • Opción 1: Mantener el cambio de la rama arregla_paquetes.
  • Opción 2: Mantener el cambio de la rama main.
  • Opción 3: Combinar ambos cambios (por ejemplo, si se requiere conservar alguna información de ambas).

Supongamos que decidimos usar la versión de arregla_paquetes (la ruta corregida). Entonces, el bloque conflictivo se debe editar para quedar como:

f = "./data/datos.txt"
f = "./data/archivo_modificado.txt" # solución: se usa la ruta corregida de arregla_paquetes

Importante: Asegúrate de eliminar todos los marcadores (<<<<<<<, =======, >>>>>>>).

4.2. Confirmar la Resolución del Conflicto

Una vez que hayas editado y guardado el archivo:

  1. Marca el archivo como resuelto:

    git add main.py
  2. Finaliza el merge realizando el commit:

    git commit -m "Resuelto conflicto entre main y arregla_paquetes en main.py"

5. Explicación del Origen de los Conflictos

Los conflictos en Git se producen cuando:

  • Dos o más ramas han modificado la misma parte de un archivo de forma diferente.
  • Git no puede determinar automáticamente cuál de las versiones es la correcta, por lo que requiere intervención manual.

En nuestro ejemplo, el conflicto surgió porque en ambas ramas se modificó la segunda asignación de la variable f de manera incompatible:

  • En main, se actualizó únicamente el comentario.
  • En arregla_paquetes, se modificó la ruta del archivo.

Git, al intentar fusionar, detectó la discrepancia en el mismo bloque de código y, por lo tanto, insertó los marcadores para que el desarrollador decida cuál versión conservar.

Conclusión

En este tutorial aprendiste a:

  • Configurar un escenario para generar conflictos en Git modificando la misma línea de código en dos ramas diferentes.
  • Identificar los marcadores de conflicto (<<<<<<<, =======, >>>>>>>) que Git inserta en el archivo.
  • Resolver manualmente el conflicto eligiendo la versión adecuada (o combinando ambas) y completando el proceso de merge.

La resolución de conflictos es una habilidad fundamental para trabajar en equipo y mantener la integridad del código fuente en proyectos colaborativos. ¡Practica estos pasos para familiarizarte con el flujo de trabajo en Git!