¿Por qué git dice "No es posible extraer porque tienes archivos no fusionados"?

Resuelto Harsukh Makwana asked hace 10 años • 13 respuestas

Cuando intento acceder al directorio de mi proyecto en la terminal, veo el siguiente error:

harsukh@harsukh-desktop:~/Sites/branch1$ git pull origin master
U app/config/app.php
U app/config/database.php
U app/routes.php
Pull is not possible because you have unmerged files.
Please, fix them up in the work tree, and then use 'git add/rm <file>'
as appropriate to mark resolution, or use 'git commit -a'.

¿Por qué dice git "Pull is not possible because you have unmerged files"y cómo puedo resolverlo?

Harsukh Makwana avatar Oct 15 '14 14:10 Harsukh Makwana
Aceptado

Lo que está sucediendo actualmente es que tiene un determinado conjunto de archivos que intentó fusionar anteriormente, pero arrojaron conflictos de fusión. Idealmente, si uno tiene un conflicto de fusión, debería resolverlo manualmente y confirmar los cambios usando git add file.name && git commit -m "removed merge conflicts". Ahora, otro usuario actualizó los archivos en cuestión en su repositorio y envió sus cambios al repositorio ascendente común.

Sucede que sus conflictos de fusión de (probablemente) la última confirmación no se resolvieron, por lo que sus archivos no se fusionaron correctamente y, por lo tanto, el indicador U( unmerged) para los archivos. Entonces, ahora, cuando haces un archivo git pull, git arroja el error, porque tienes alguna versión del archivo, que no está resuelta correctamente.

Para resolver esto, deberá resolver los conflictos de fusión en cuestión y agregar y confirmar los cambios antes de poder realizar un archivo git pull.

Reproducción de muestra y resolución del problema:

# Note: commands below in format `CUURENT_WORKING_DIRECTORY $ command params`
Desktop $ cd test

Primero, creemos la estructura del repositorio.

test $ mkdir repo && cd repo && git init && touch file && git add file && git commit -m "msg"
repo $ cd .. && git clone repo repo_clone && cd repo_clone
repo_clone $ echo "text2" >> file && git add file && git commit -m "msg" && cd ../repo
repo $ echo "text1" >> file && git add file && git commit -m "msg" && cd ../repo_clone

Ahora estamos en repo_clone, y si haces un git pull, generará conflictos.

repo_clone $ git pull origin master
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/anshulgoyal/Desktop/test/test/repo
 * branch            master     -> FETCH_HEAD
   24d5b2e..1a1aa70  master     -> origin/master
Auto-merging file
CONFLICT (content): Merge conflict in file
Automatic merge failed; fix conflicts and then commit the result.

Si ignoramos los conflictos en el clon y hacemos más confirmaciones en el repositorio original ahora,

repo_clone $ cd ../repo
repo $ echo "text1" >> file && git add file && git commit -m "msg" && cd ../repo_clone

Y luego hacemos un git pull, obtenemos

repo_clone $ git pull
U   file
Pull is not possible because you have unmerged files.
Please, fix them up in the work tree, and then use 'git add/rm <file>'
as appropriate to mark resolution, or use 'git commit -a'.

Tenga en cuenta que el fileahora está en un estado no fusionado y si hacemos un git status, podemos ver claramente lo mismo:

repo_clone $ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 1 different commit each, respectively.
  (use "git pull" to merge the remote branch into yours)

You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both modified:      file

Entonces, para resolver esto, primero debemos resolver el conflicto de fusión que ignoramos anteriormente.

repo_clone $ vi file

y establecer su contenido en

text2
text1
text1

y luego agregarlo y confirmar los cambios.

repo_clone $ git add file && git commit -m "resolved merge conflicts"
[master 39c3ba1] resolved merge conflicts
Anshul Goyal avatar Nov 28 '2014 10:11 Anshul Goyal

Si no desea fusionar los cambios y aún desea actualizar su local, ejecute:

git reset --hard HEAD  

Esto restablecerá su local con HEAD y luego activará su control remoto usando git pull.

Si ya confirmó su combinación localmente (pero aún no la ha enviado de forma remota) y desea revertirla también:

git reset --hard HEAD~1 
Santosh avatar Jul 11 '2016 12:07 Santosh

Está intentando agregar una nueva confirmación más en su sucursal local mientras su directorio de trabajo no está limpio. Como resultado, Git se niega a realizar la extracción. Considere los siguientes diagramas para visualizar mejor el escenario:

remoto: A <- B <- C <- D
local: A <- B*
(*indica que tiene varios archivos que han sido modificados pero no confirmados).

Hay dos opciones para afrontar esta situación. Puede descartar los cambios en sus archivos o conservarlos.

Opción uno: desechar los cambios.
Puede usarlos git checkoutpara cada archivo no fusionado o puede usarlos git reset --hard HEADpara restablecer todos los archivos en su rama a HEAD. Por cierto, HEAD en tu sucursal local es B, sin asterisco. Si elige esta opción, el diagrama se convierte en:

remoto: A <- B <- C <- D
local: A <- B

Ahora, cuando tiras, puedes avanzar rápidamente tu rama con los cambios del maestro. Después de tirar, tu rama se verá como maestra:

local: A <- B <- C <- D

Opción dos: conservar los cambios
Si desea conservar los cambios, primero deberá resolver cualquier conflicto de combinación en cada uno de los archivos. Puede abrir cada archivo en su IDE y buscar los siguientes símbolos:

<<<<<<< HEAD
// tu versión del código
=======
// la versión del código del control remoto
>>>>>>>

Git te presenta dos versiones de código. El código contenido dentro de los marcadores HEAD es la versión de su sucursal local actual. La otra versión es la que viene desde el mando. Una vez que haya elegido una versión del código (y haya eliminado el otro código junto con los marcadores), puede agregar cada archivo a su área de preparación escribiendo git add. El último paso es confirmar el resultado escribiendo git commit -m con un mensaje apropiado. En este punto, nuestro diagrama se ve así:

remoto: A <- B <- C <- D
local: A <- B <- C'

Aquí he etiquetado la confirmación que acabamos de realizar como C' porque es diferente de la confirmación C en el control remoto. Ahora, si intentas tirar, obtendrás un error de avance no rápido. Git no puede reproducir los cambios en el control remoto en su rama, porque tanto su rama como el control remoto se han separado del compromiso del ancestro común B. En este punto, si desea realizar un pull, puede hacer otro git mergeo git rebasesu rama en el control remoto.

Dominar Git requiere ser capaz de comprender y manipular listas enlazadas unidireccionales. Espero que esta explicación te haga pensar en la dirección correcta sobre el uso de Git.

Tim Biegeleisen avatar Dec 01 '2014 09:12 Tim Biegeleisen

Hay una solución sencilla. Pero para eso primero necesitarás aprender lo siguiente.

vimdiff

Para eliminar conflictos, puedes usar

git mergetool

El comando anterior básicamente abre un archivo local, un archivo mixto y un archivo remoto (3 archivos en total), para cada archivo en conflicto. Los archivos locales y remotos son sólo para su referencia y, al usarlos, puede elegir qué incluir (o no) en el archivo mixto. Y simplemente guarde y cierre el archivo.

Pawan Seerwani avatar Dec 03 '2014 19:12 Pawan Seerwani

Si desea desplegar una rama remota para ejecutarla localmente (por ejemplo, con fines de revisión o prueba) y cuando obtiene $ git pullconflictos de fusión locales:

$ git checkout REMOTE-BRANCH
$ git pull  (you get local merge conflicts)
$ git reset --hard HEAD (discards local conflicts, and resets to remote branch HEAD)
$ git pull (now get remote branch updates without local conflicts)
user5245397 avatar Aug 03 '2016 15:08 user5245397