Qué es un conflicto (y qué no)
Git combina dos ramas línea por línea. Si cada rama cambió partes distintas de un archivo, las mezcla sola y no te enteras. Hay conflicto cuando las dos cambiaron las mismas líneas, o cuando una rama borró un archivo que la otra modificó: ahí Git no puede adivinar cuál versión es la buena.
Un conflicto no es un error ni daña tu trabajo. Tus commits siguen intactos; el merge simplemente queda a medias hasta que lo termines o lo canceles.
Paso 1: Git se detiene
Imagina que estás en main y quieres traer rama-ana. Las dos ramas cambiaron la línea pan del archivo lista.txt. Lanzas el merge:
git merge rama-ana
Git responde con algo así:
Auto-merging lista.txt
CONFLICT (content): Merge conflict in lista.txt
Automatic merge failed; fix conflicts and then commit the result.Git muestra sus mensajes en el idioma de tu sistema: si lo tienes en español, verás lo mismo traducido. La palabra clave es CONFLICT, que nombra el archivo afectado.
Paso 2: Mira qué archivos tienen conflicto
git status
On branch main
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 mark resolution)
both modified: lista.txt
no changes added to commit (use "git add" and/or "git commit -a")Los archivos bajo Unmerged paths son los que debes resolver. both modified significa que las dos ramas los cambiaron. Si son muchos, esta lista corta muestra solo los que siguen en conflicto:
git diff --name-only --diff-filter=U
Paso 3: Lee los marcadores
Abre el archivo en tu editor. Git escribió dentro las dos versiones, separadas por marcadores:
Compras
leche
<<<<<<< HEAD
pan de centeno
=======
pan integral
>>>>>>> rama-ana
huevos
- Entre
<<<<<<< HEADy=======está tu versión: la de la rama en la que estás parado (aquí,main). - Entre
=======y>>>>>>> rama-anaestá la versión que llega, la de la rama que intentas traer. - Las líneas fuera de los marcadores no tuvieron conflicto y ya están mezcladas.
Paso 4: Decide cómo debe quedar y edita
Tienes tres opciones: quedarte con una de las dos versiones, combinar ambas o escribir algo nuevo. Cualquiera que elijas, borra las tres líneas de marcadores. Si decidimos combinar las dos ideas, el archivo termina así:
Compras
leche
pan integral de centeno
huevos
Antes de seguir, comprueba que no quedó ningún marcador olvidado:
git diff --check
Si no imprime nada, el archivo está limpio. Si queda alguno, avisa con leftover conflict marker y el número de línea. Este comando también señala espacios sobrantes al final de línea, que puedes corregir o ignorar.
git diff --check antes de marcar el archivo como resuelto.
Paso 5: Marca el archivo como resuelto y termina
Avisa a Git de que ese archivo ya está listo:
git add lista.txt
Cuando no queden archivos sin resolver, cierra el merge con un commit:
git commit
Git abre tu editor con el mensaje ya escrito (Merge branch 'rama-ana'); guárdalo y ciérralo. Con git merge --continue logras exactamente lo mismo. Si aún queda algún archivo en conflicto, Git se niega a hacer el commit. Al terminar, el historial muestra la unión de las dos ramas:
git log --oneline --graph
* 717c8a6 Merge branch 'rama-ana'
|\
| * 6ca490d pan integral
* | 256c106 pan de centeno
|/
* 1551e56 baseLos códigos de commit de tu repositorio serán distintos; lo importante es el commit de merge con dos padres arriba del todo.
Atajo: quedarte con una versión completa de un archivo
A veces no hay nada que combinar y quieres una versión entera. Para quedarte con la de tu rama:
git checkout --ours -- lista.txt
Y para quedarte con la que llega de la otra rama:
git checkout --theirs -- lista.txt
Después, git add lista.txt y sigue con el commit como en el paso 5.
Cuando una rama borró el archivo
El otro tipo de conflicto aparece cuando una rama borró un archivo que la otra modificó:
CONFLICT (modify/delete): lista.txt deleted in rama-borra and modified in HEAD. Version HEAD of lista.txt left in tree.
Automatic merge failed; fix conflicts and then commit the result.En git status el archivo aparece como deleted by them (la rama que traes lo borró) o deleted by us (lo borró la tuya). Aquí no hay marcadores que editar: decides si el archivo se queda o se va. Para conservarlo:
git add lista.txt
Para aceptar el borrado:
git rm lista.txt
En ambos casos, termina con git commit.
Si te arrepientes, cancela
Mientras el merge siga a medias, puedes abandonarlo y volver a como estabas antes de empezar:
git merge --abort
--abort no podrá reconstruirlos. Guarda tu trabajo con un commit antes de traer otra rama.
Preguntas frecuentes
¿Y si el conflicto aparece en un git pull o en un rebase?
git pull descarga y hace un merge, así que el proceso es el de esta guía. En un rebase el flujo es parecido, pero se termina con git rebase --continue y hay un detalle que confunde: --ours y --theirs se invierten. Durante un rebase, --ours es la rama sobre la que estás reaplicando tus commits y --theirs es tu propio commit. La guía Merge vs. rebase explica cuándo conviene cada uno.
¿Cómo se resuelve un conflicto en una imagen o un PDF?
Git no puede mezclar dentro de un archivo binario, así que no escribe marcadores: deja en tu carpeta la versión de tu rama y lo declara en conflicto. Elige una de las dos con git checkout --ours -- archivo o git checkout --theirs -- archivo, y luego git add archivo.
¿Puedo ver cómo era el texto original antes de los dos cambios?
Sí. Con este ajuste, los próximos conflictos incluirán una tercera sección con la versión base:
git config --global merge.conflictStyle diff3
El archivo quedará así, con el original entre ||||||| y =======:
Compras
leche
<<<<<<< HEAD
pan de centeno
||||||| 7ecd704
pan
=======
pan integral
>>>>>>> rama-ana
huevos
Ver qué había antes suele aclarar quién cambió qué.
¿Hay una forma más cómoda que editar los marcadores a mano?
Sí. Muchos editores de código muestran los conflictos con botones para elegir cada lado, y Git trae git mergetool, que abre la herramienta de comparación que tengas configurada. Editar a mano sigue siendo útil porque funciona en cualquier sitio y te obliga a leer lo que cambió.
¿Cómo evito tener tantos conflictos?
No se pueden eliminar, pero sí reducir: trae los cambios de main a tu rama con frecuencia, así resuelves diferencias pequeñas en vez de una enorme al final; haz commits pequeños y enfocados; y avisa a tu equipo cuando vayas a tocar un archivo que otras personas también están cambiando.