Git básico

Fusionar y resolver conflictos

Lección 7 de 8 · 14 min

Fusionar es lo normal; el conflicto es la excepción

Terminaste el formato nuevo en su rama y se aprobó. Toca llevarlo a la principal, y eso es una fusión: traer a la rama donde estás los commits de otra.

La inmensa mayoría de las fusiones no dan ningún problema. Git compara las dos líneas de trabajo y, si los cambios están en archivos distintos -o en partes distintas del mismo archivo-, los junta él solo y no te entera.

Una fusión normal
# Situarse en la rama que va a RECIBIR el trabajo
git switch main

# Traer los commits de la otra
git merge formato-nuevo
Resultado
Updating a91c4e2..5b1d7c4
Fast-forward
 cotizacion-servicios.md | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

El orden importa y se olvida siempre: primero te mueves a la rama que va a recibir y luego nombras la que aporta. git merge siempre trae hacia donde estás parado.

Cuándo aparece un conflicto

Solo hay una causa: las dos ramas cambiaron las mismas líneas del mismo archivo. Git no tiene forma de saber cuál de las dos versiones vale, así que se detiene y te lo pregunta.

Eso no es un fallo, es lo correcto. Un sistema que eligiera solo acabaría borrando el trabajo de alguien en silencio, que es exactamente lo que Git existe para evitar.

Así se anuncia
git merge formato-nuevo
Resultado
Auto-merging cotizacion-servicios.md
CONFLICT (content): Merge conflict in cotizacion-servicios.md
Automatic merge failed; fix conflicts and then commit the result.

Antes de nada: siempre hay marcha atrás. git merge --abort cancela la fusión y deja todo exactamente como estaba antes de empezar. No pierdes nada.

Saber que ese comando existe es lo que permite abrir el archivo con calma en vez de entrar en pánico.

Qué escribe Git dentro del archivo

Git no rompe nada: deja las dos versiones, una encima de la otra, separadas por unos marcadores. El archivo se abre con cualquier editor y se lee perfectamente.

El aspecto real de un conflicto
## Condiciones comerciales

<<<<<<< HEAD
El domicilio se cobra aparte segun la zona de la ciudad.
=======
El domicilio esta incluido en compras superiores a 500.000.
>>>>>>> formato-nuevo

El tiempo de respuesta es de 24 horas habiles.

Cómo se leen los tres marcadores

<<<<<<< HEAD

Abre la versión de la rama en la que estás, la que recibe la fusión.

Recuerda que HEAD significa «aquí estoy parado». Suele ser main.

=======

La línea divisoria. Arriba tu versión, abajo la que viene de la otra rama.

No separa «bueno» de «malo»: separa dos cambios legítimos que se pisan.

&gt;&gt;&gt;&gt;&gt;&gt;&gt; formato-nuevo

Cierra la versión que llega desde la otra rama, y lleva su nombre para que sepas de dónde salió.

Resolverlo, paso a paso

  1. Ver qué archivos están en conflicto

    git status los lista bajo Unmerged paths. Puede ser uno o pueden ser seis: se resuelven todos antes de cerrar la fusión.

  2. Abrir el archivo y decidir

    Tienes tres salidas legítimas: quedarte con tu versión, quedarte con la que llega, o escribir una tercera que combine las dos. Esta última es la más frecuente y la que ningún comando puede hacer por ti.

    En el ejemplo, lo razonable sería: «El domicilio se cobra aparte según la zona, salvo en compras superiores a 500.000».

  3. Borrar los tres marcadores

    Las líneas <<<<<<<, ======= y >>>>>>> se eliminan. No son parte del texto: son la pregunta de Git, y tienen que desaparecer con la respuesta.

  4. Comprobar que no quedó ninguno

    git diff --check avisa si quedó algún marcador suelto.

    Es el error más común y el más tonto: se resuelve el conflicto, se olvida un ======= y se guarda un archivo roto en el historial.

  5. Marcar como resuelto y cerrar

    git add cotizacion-servicios.md y luego git commit.

    El add es lo que le dice a Git «ya decidí». El commit de fusión trae un mensaje escrito solo, que puedes dejar tal cual.

Los editores modernos -Visual Studio Code, por ejemplo- pintan el conflicto con botones de Aceptar el actual / Aceptar el entrante / Aceptar ambos. Hacen exactamente lo mismo que estás haciendo a mano, y borran los marcadores por ti. Merece la pena resolver dos o tres a mano primero, para saber qué está tocando ese botón.

Preguntas que aparecen aquí

¿Cómo evito los conflictos?

No se evitan del todo, se hacen pequeños. Tres costumbres bastan: ramas cortas que viven días y no meses, git pull antes de empezar cada jornada, y repartir el trabajo por archivos cuando se pueda.

Una rama de tres meses no da un conflicto: da cuarenta.

Me equivoqué al resolver y ya hice commit

No pasa nada: es un commit como cualquier otro. Editas el archivo, lo dejas bien y haces otro commit encima.

No hay que reescribir la historia por esto, sobre todo si ya lo compartiste (lección 5).

¿Qué es un conflicto de borrado?

Una rama modificó un archivo y la otra lo borró. Git no puede inventarse la intención, así que pregunta.

Se resuelve decidiendo: git add archivo para conservarlo, o git rm archivo para confirmar el borrado.

Me hablan de rebase, ¿es mejor que merge?

git rebase es otra forma de juntar trabajo: en vez de unir las dos líneas, reescribe tus commits como si hubieran salido del final de la otra rama. Deja un historial más recto.

Reescribe identificadores, así que le aplica la misma regla de la lección 5: nunca sobre commits que ya compartiste. Con merge tienes cubierto todo este curso.

Compruébalo tú mismo

Dos personas cambiaron archivos distintos de la misma carpeta. ¿Habrá conflicto?

Abres un conflicto y no te atreves a tocarlo. ¿Cómo vuelves atrás?

Resolviste el texto pero dejaste un ======= en el archivo. ¿Qué pasa?

Lo que sigue

Ya sabes todo lo que se usa a diario. La última lección cierra con dos herramientas cómodas -guardar trabajo a medias y marcar versiones- y con el proyecto final: montar el repositorio de un negocio de verdad, que casi nunca es solo código.

Siguiente: Etiquetas, versiones y proyecto final

Continuar ← Trabajar con GitHub