W3docs

conflictos de fusión

Aprende qué causa los conflictos de fusión en Git, cómo leer los marcadores y cómo resolverlos, abortarlos o prevenirlos con los comandos adecuados.

Un conflicto de fusión ocurre cuando Git no puede reconciliar automáticamente dos conjuntos de cambios. Se produce cuando dos ramas modifican las mismas líneas del mismo archivo de formas distintas, o cuando una rama elimina un archivo que la otra rama ha editado. Como Git no puede saber qué versión es la correcta, detiene la fusión y te deja la decisión a ti.

Esta página explica por qué ocurren los conflictos, cómo reproducir uno, cómo leer los marcadores que Git inserta en tus archivos y las distintas formas de resolver, abortar o incluso prevenir un conflicto. El comando git merge es el que combina dos ramas y es donde la mayoría de los conflictos aparecen.

Git gestiona las fusiones mejor que la mayoría de los sistemas de control de versiones e integra los cambios automáticamente siempre que los dos lados tocan partes distintas de un archivo. Un conflicto, por tanto, no es un error en tu flujo de trabajo — es Git pidiendo una decisión humana. Cuando no puede decidir, marca el archivo como conflictivo y detiene la fusión para que no se pierda nada.

mergeconflicts

¿Cuándo ocurren los conflictos?

No toda fusión produce un conflicto. Saber cuándo es probable que ocurra uno te ayuda a evitar sorpresas:

  • Las mismas líneas editadas en ambos lados — el caso clásico. Dos ramas cambian la misma línea de example.txt de formas diferentes.
  • Un archivo editado en una rama y eliminado en la otra — Git no puede decidir si conservar las ediciones o respetar la eliminación.
  • Discrepancias en espacios en blanco, finales de línea o codificación — cambios que parecen idénticos pueden seguir generando conflicto si los bytes difieren.

Cuando las dos ramas tocan líneas diferentes o archivos diferentes, Git las fusiona automáticamente sin ningún conflicto.

Interrupciones comunes de la fusión

Git puede detener una fusión en dos puntos distintos, y cada caso requiere una solución diferente. Conviene saber cuál estás viendo.

Fallo de fusión al inicio

Git se niega a iniciar una fusión cuando los cambios no confirmados en tu directorio de trabajo o área de preparación serían sobreescritos por los commits entrantes. Esto no es un conflicto de contenido — es Git protegiendo trabajo que aún no has confirmado. Para tomar el control de tu estado local, utiliza git stash (guarda los cambios temporalmente), git commit (guárdalos), git checkout o git reset (descártalos); luego vuelve a ejecutar la fusión. El mensaje tiene este aspecto:

error: Your local changes to the following files would be overwritten by merge:
	example.txt
Please commit your changes or stash them before you merge.
Aborting

Fallo durante la fusión

Un fallo durante la fusión significa que Git empezó a combinar las ramas pero encontró un conflicto de contenido real entre tu rama actual y la rama que estás fusionando. La fusión queda a medias para que puedas resolverlo. El mensaje tiene este aspecto:

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

Crear un conflicto de fusión

Puedes reproducir un conflicto en un repositorio de prueba para practicar su resolución de forma segura. Comienza creando un repositorio con un único archivo confirmado:

mkdir test-dir
cd test-dir
git init .
echo "some content" > example.txt
git add example.txt
git commit -m "initial commit"
[master (root-commit) a45c22d] initial commit
1 file changed, 1 insertion(+)
create mode 100644 example.txt

Esto crea un directorio llamado test-dir, inicializa un repositorio y confirma example.txt con la línea some content. Ahora tenemos una rama (master) y un archivo. A continuación, crea una segunda rama y cambia la misma línea — esto es lo que hace posible el conflicto:

git checkout -b branch_to_merge
echo "completely different content to merge later" > example.txt
git commit -m "edit the content of example.txt to make a conflict"
[branch_to_merge 4221135] edit the content of example.txt to make a conflict
1 file changed, 1 insertion(+), 1 deletion(-)

git checkout -b branch_to_merge crea la rama y cambia a ella. Sobreescribimos example.txt y confirmamos el cambio, por lo que esta rama ahora tiene una versión diferente de esa línea. Vuelve a master y cambia el mismo archivo de una forma distinta:

git checkout master
Switched to branch 'master'
echo "content to add" >> example.txt
git commit -m "added content to example.txt"
[master 11ab34b] added content to example.txt
1 file changed, 1 insertion(+)

Ahora ambas ramas tienen su propio commit que toca example.txt. Ejecuta la fusión y Git informa del conflicto que no puede resolver por sí solo:

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

Identificar conflictos de fusión

Además del mensaje que imprime la fusión, git status te indica exactamente qué archivos están en conflicto listándolos bajo Unmerged paths:

git status
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 mark resolution)
	both modified:   example.txt

both modified significa que el archivo cambió en ambos lados. Abre o ejecuta cat sobre el archivo para ver los marcadores de conflicto que Git insertó:

cat example.txt
<<<<<<< HEAD
some content
content to add
=======
completely different content to merge later
>>>>>>> branch_to_merge

Lee los tres marcadores así:

  • <<<<<<< HEAD — inicio del conflicto. Todo lo que hay debajo hasta ======= es el contenido de tu rama actual (master, hacia donde apunta HEAD).
  • ======= — la línea divisoria entre las dos versiones.
  • >>>>>>> branch_to_merge — fin del conflicto. Las líneas entre ======= y este marcador provienen de la rama que estás fusionando.

Para descartar toda la fusión y volver al estado exacto antes de comenzarla, ejecuta git merge --abort. Puedes leer más sobre los marcadores en la página de git merge.

Resolver conflictos de fusión

Resolver manualmente

Abre el archivo en conflicto en tu editor, decide cuál debe ser el contenido final y elimina los tres marcadores (<<<<<<<, =======, >>>>>>>). Puedes conservar un lado, el otro o una combinación hecha a mano de ambos. Por ejemplo, conservar los dos fragmentos de contenido da como resultado:

some content
content to add
completely different content to merge later

Una vez eliminados los marcadores y correcto el contenido, prepara el archivo con git add y confirma para finalizar la fusión:

git add example.txt
git commit -m "resolve merge conflict in example.txt"

Ejecutar git commit después de un conflicto crea un commit de fusión que une los historiales de ambas ramas.

Resolver eligiendo un lado

Cuando simplemente quieres conservar la versión completa de un archivo de una rama, no necesitas editar manualmente. Extrae el lado que quieres, luego prepáralo y confírmalo:

git checkout --ours example.txt    # keep the version from the current branch (master)
git checkout --theirs example.txt  # keep the version from the incoming branch
git add example.txt

--ours conserva el contenido de tu rama actual; --theirs conserva el contenido de la rama entrante.

Resolver con una herramienta visual

Para conflictos más grandes, git mergetool abre una herramienta de diferencias lado a lado configurada para que puedas resolver los conflictos de forma interactiva en lugar de editar los marcadores manualmente. Ejecuta git mergetool para recorrer cada archivo en conflicto, o git mergetool example.txt para uno específico.

Abortar una fusión

Si decides que la fusión fue un error o prefieres empezar de nuevo con un árbol de trabajo limpio, abórtala:

git merge --abort

Esto restaura tu rama y tu directorio de trabajo al estado exacto en que estaban antes de ejecutar git merge — sin marcadores, sin archivos a medio fusionar. Úsalo siempre que el conflicto sea más de lo que quieres gestionar en este momento.

Prevenir conflictos de fusión

Los conflictos son normales, pero puedes reducir con qué frecuencia y con qué intensidad te afectan:

  • Fusiona o haz rebase desde la rama principal con frecuencia para que tu rama nunca se aleje demasiado de ella.
  • Mantén los commits pequeños y enfocados, y evita reformateos extensos en el mismo cambio que ediciones de lógica.
  • Comunícate para que dos personas no estén reescribiendo el mismo archivo al mismo tiempo.
  • Previsualiza el solapamiento con git diff antes de fusionar para ver qué líneas podrían colisionar.

Hoja de referencia de comandos

Estos son los comandos a los que acudes con más frecuencia al gestionar conflictos:

HerramientaDescripción
git statusAyuda a encontrar los archivos en conflicto.
git mergetoolAbre una herramienta visual de diferencias para resolver conflictos de forma interactiva.
git diffMuestra las diferencias entre commits, ramas o archivos para ayudar a identificar posibles conflictos antes de fusionar.
git checkout --ours/--theirsReemplaza el archivo en conflicto con el contenido de la rama actual o de la entrante.
git reset --mixedRetira los archivos del área de preparación pero deja el directorio de trabajo sin cambios.
git merge --abortAborta la fusión actual y restaura el directorio de trabajo al estado anterior al inicio de la fusión.
git resetRestablece el índice para que coincida con HEAD, lo que ayuda a retirar archivos en conflicto del área de preparación.

Práctica

Práctica
¿Cuáles son los aspectos del manejo de conflictos de fusión en Git?
¿Cuáles son los aspectos del manejo de conflictos de fusión en Git?
Was this page helpful?