Cómo comprobar si un archivo tiene conflictos en Git

GitGitBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderás cómo identificar y comprender los conflictos de fusión (merge conflicts) en Git. Simularemos un escenario de conflicto realizando cambios conflictivos en el mismo archivo en diferentes ramas (branches) y luego intentando fusionarlos.

Utilizarás el comando git status para detectar la presencia de conflictos y luego examinar el archivo conflictivo para ver los marcadores de conflicto que inserta Git. Finalmente, verificarás que los archivos sin conflictos no se marcan como tales.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL git(("Git")) -.-> git/BasicOperationsGroup(["Basic Operations"]) git(("Git")) -.-> git/BranchManagementGroup(["Branch Management"]) git/BasicOperationsGroup -.-> git/add("Stage Files") git/BasicOperationsGroup -.-> git/status("Check Status") git/BasicOperationsGroup -.-> git/commit("Create Commit") git/BranchManagementGroup -.-> git/branch("Handle Branches") git/BranchManagementGroup -.-> git/checkout("Switch Branches") git/BranchManagementGroup -.-> git/merge("Merge Histories") subgraph Lab Skills git/add -.-> lab-560023{{"Cómo comprobar si un archivo tiene conflictos en Git"}} git/status -.-> lab-560023{{"Cómo comprobar si un archivo tiene conflictos en Git"}} git/commit -.-> lab-560023{{"Cómo comprobar si un archivo tiene conflictos en Git"}} git/branch -.-> lab-560023{{"Cómo comprobar si un archivo tiene conflictos en Git"}} git/checkout -.-> lab-560023{{"Cómo comprobar si un archivo tiene conflictos en Git"}} git/merge -.-> lab-560023{{"Cómo comprobar si un archivo tiene conflictos en Git"}} end

Ejecutar git status para detectar conflictos

En este paso, aprenderemos cómo usar el comando git status para detectar conflictos en tu repositorio de Git. Los conflictos ocurren cuando se realizan dos cambios diferentes en la misma parte de un archivo y Git no sabe qué cambio mantener.

Primero, asegúrate de estar en el directorio de tu proyecto. Abre tu terminal y navega hasta el directorio my-time-machine:

cd ~/project/my-time-machine

Ahora, simulemos un conflicto. Imagina que tú y un colaborador hicieron cambios en el archivo message.txt al mismo tiempo, pero en diferentes ramas (branches). Para este laboratorio, crearemos manualmente un escenario que resulte en un conflicto.

Primero, creemos una nueva rama y hagamos un cambio.

git branch feature/greeting
git checkout feature/greeting
echo "Hope you are doing well!" >> message.txt
git add message.txt
git commit -m "Add a greeting"

Ahora, cambiemos de nuevo a la rama master y hagamos un cambio diferente en el mismo archivo.

git checkout master
echo "This is an important message." >> message.txt
git add message.txt
git commit -m "Add an important message"

Ahora tenemos dos cambios diferentes en message.txt en dos ramas diferentes. Cuando intentemos fusionar estas ramas, Git detectará un conflicto.

Intentemos fusionar la rama feature/greeting en master:

git merge feature/greeting

Deberías ver una salida que indique un conflicto:

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

Esta salida nos dice que hay un conflicto de fusión (merge conflict) en el archivo message.txt. Git no pudo fusionar automáticamente los cambios porque se solapaban.

Ahora, ejecutemos git status para ver cómo Git informa el conflicto:

git status

La salida se verá algo así:

On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to resolve merge conflicts)
        both modified:   message.txt

no changes added to commit (use "git add" and/or "git commit -a)")

La salida de git status muestra claramente que estamos "On branch master" y tenemos "unmerged paths". También enumera message.txt bajo "Unmerged paths" e indica que fue "both modified". Así es como git status te ayuda a identificar los archivos que tienen conflictos de fusión.

Comprender cómo usar git status para detectar conflictos es el primer paso para resolverlos. En los siguientes pasos, aprenderemos cómo examinar el archivo conflictivo y resolver el conflicto.

Verificar el archivo en busca de marcadores de conflicto

En el paso anterior, vimos que git status informó un conflicto en message.txt. Ahora, examinemos el archivo en sí para ver cómo Git marca las secciones conflictivas.

Asegúrate de que todavía estés en el directorio ~/project/my-time-machine.

Podemos usar el comando cat para ver el contenido del archivo:

cat message.txt

La salida se verá algo así:

Hello, Future Me
<<<<<<< HEAD
This is an important message.
=======
Hope you are doing well!
>>>>>>> feature/greeting

Observa los marcadores especiales que Git ha agregado al archivo:

  • <<<<<<< HEAD: Esto marca el inicio de los cambios en la rama actual (que es HEAD, que apunta a master en este caso).
  • =======: Este es un separador entre los cambios de las dos ramas.
  • >>>>>>> feature/greeting: Esto marca el final de los cambios de la rama desde la que estás fusionando (feature/greeting).

Estos marcadores te muestran exactamente dónde ocurrió el conflicto y cuáles son las diferentes versiones de las líneas conflictivas. Las líneas entre <<<<<<< HEAD y ======= son los cambios de tu rama actual (master), y las líneas entre ======= y >>>>>>> feature/greeting son los cambios de la rama que estás fusionando (feature/greeting).

Tu tarea ahora es editar manualmente este archivo y decidir qué cambios mantener. Debes eliminar los marcadores de conflicto y las líneas que no quieres mantener, dejando solo el contenido final deseado.

Por ejemplo, si quisieras mantener ambos mensajes, editarías el archivo para que se vea así:

Hello, Future Me
This is an important message.
Hope you are doing well!

O, si solo quisieras mantener el mensaje de la rama master, editarías el archivo para que se vea así:

Hello, Future Me
This is an important message.

Usa el editor nano para abrir y editar el archivo message.txt:

nano message.txt

Edita el archivo para resolver el conflicto eliminando los marcadores de conflicto y eligiendo el contenido que quieres mantener. Para este laboratorio, mantengamos ambos mensajes.

Después de editar, el contenido del archivo debe ser:

Hello, Future Me
This is an important message.
Hope you are doing well!

Presiona Ctrl + X para salir de nano, luego presiona Y para guardar los cambios y, finalmente, presiona Enter para confirmar el nombre del archivo.

Al editar manualmente el archivo y eliminar los marcadores de conflicto, le estás indicando a Git cómo combinar los cambios conflictivos. Este es un paso crucial para resolver los conflictos de fusión (merge conflicts).

Probar archivos sin conflictos

En los pasos anteriores, identificamos y examinamos un archivo con un conflicto de fusión (merge conflict) (message.txt). Sin embargo, durante una fusión, también pueden haber archivos que se hayan modificado en ambas ramas (branches) pero sin conflictos. Git fusiona automáticamente estos archivos.

En este paso, crearemos un nuevo archivo en una de las ramas y veremos cómo Git lo maneja durante el proceso de fusión. Esto nos ayudará a entender que los conflictos solo ocurren cuando los cambios se solapan en el mismo archivo.

Asegúrate de que todavía estés en el directorio ~/project/my-time-machine y en la rama master (donde ocurrió el conflicto de fusión).

Creemos un nuevo archivo llamado notes.txt en la rama master:

echo "Important notes for the project." > notes.txt
git add notes.txt
git commit -m "Add project notes"

Ahora, cambiemos de nuevo a la rama feature/greeting:

git checkout feature/greeting

En esta rama, el archivo notes.txt aún no existe. Creemos un archivo diferente aquí, por ejemplo, todo.txt:

echo "Things to do: finish the lab." > todo.txt
git add todo.txt
git commit -m "Add a todo list"

Ahora, cambiemos de nuevo a la rama master e intentemos la fusión nuevamente. Aunque ya hemos resuelto el conflicto en message.txt, el proceso de fusión debe completarse.

git checkout master
git merge feature/greeting

Esta vez, dado que ya hemos resuelto el conflicto en message.txt y lo hemos agregado al área de preparación (staging area) (aunque no mostramos explícitamente ese paso después de editar, Git a menudo prepara el archivo después de la resolución manual del conflicto), Git debería poder completar la fusión. Puedes ver una salida que indique que la fusión se ha completado.

Veamos el estado nuevamente:

git status

La salida ahora debería mostrar que estás "On branch master" y que el árbol de trabajo está limpio, lo que significa que no hay cambios pendientes ni rutas no fusionadas.

On branch master
nothing to commit, working tree clean

Ahora, veamos si los archivos de ambas ramas están presentes en la rama master:

ls

Deberías ver tanto message.txt, notes.txt (de la rama master) y todo.txt (de la rama feature/greeting) en la lista.

message.txt  notes.txt  todo.txt

Esto demuestra que Git fusionó con éxito los cambios de feature/greeting, incluyendo el nuevo archivo todo.txt, sin ningún conflicto porque todo.txt no existía en la rama master. Los conflictos solo surgen cuando el mismo archivo tiene cambios superpuestos en las ramas que se están fusionando.

Comprender cómo Git maneja tanto los archivos con conflictos como los sin conflictos durante una fusión es esencial para gestionar efectivamente la historia de tu proyecto.

Resumen

En este laboratorio (lab), aprendimos cómo detectar conflictos en Git utilizando el comando git status. Simulamos un conflicto realizando diferentes cambios en el mismo archivo en ramas (branches) separadas y luego intentando fusionarlos (merge). La salida del comando git status indicó claramente la presencia de rutas no fusionadas y el archivo específico con el conflicto.

También exploramos cómo identificar los marcadores de conflicto dentro del propio archivo conflictivo, que Git inserta para resaltar las secciones conflictivas. Finalmente, confirmamos que los archivos sin conflictos no están marcados con estos caracteres especiales, lo que refuerza nuestra comprensión de cómo Git marca los problemas de fusión (merge issues).