Pourquoi git dit-il "Pull n'est pas possible car vous avez des fichiers non fusionnés"?

197

Lorsque j'essaie d'extraire mon répertoire de projet dans le terminal, je vois l'erreur suivante:

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'.

Pourquoi git dit-il "Pull is not possible because you have unmerged files", et comment puis-je le résoudre?

Harsukh Makwana
la source
1
Dans mon cas, je viens d'utiliser ces commandes "git add". puis "git commit -m" Test "et à la fin" git push "Erreur supprimée
Akhzar Nazir
Il vous fallait simplement ajouter "$ git add <file>" ... pour mettre à jour ce qui sera validé ou restaurer (pour annuler les modifications dans le répertoire de travail) puis valider "$ git commit", puis "$ git push" pour conclure la fusion.
find_X
Au cas où cela aiderait: j'ai remarqué que faire simplement "git add". puis l'engagement n'a pas fonctionné. J'ai dû ajouter le fichier individuel par nom, puis valider et tirer / pousser.
ouonomos

Réponses:

215

Ce qui se passe actuellement, c'est que vous avez un certain ensemble de fichiers, que vous avez essayé de fusionner plus tôt, mais ils ont généré des conflits de fusion. Idéalement, si l'on obtient un conflit de fusion, il doit les résoudre manuellement et valider les modifications en utilisant git add file.name && git commit -m "removed merge conflicts". Désormais, un autre utilisateur a mis à jour les fichiers en question sur son référentiel et a poussé ses modifications vers le référentiel amont commun.

Il se trouve que vos conflits de fusion provenant (probablement) du dernier commit n'ont pas été résolus, donc vos fichiers ne sont pas fusionnés correctement, et donc le drapeau U( unmerged) pour les fichiers. Alors maintenant, lorsque vous faites un git pull, git renvoie l'erreur, car vous avez une version du fichier, qui n'est pas correctement résolue.

Pour résoudre ce problème, vous devrez résoudre les conflits de fusion en question, puis ajouter et valider les modifications avant de pouvoir effectuer une opération git pull.

Exemple de reproduction et résolution du problème:

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

Tout d'abord, créons la structure du référentiel

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

Maintenant, nous sommes dans repo_clone, et si vous faites un git pull, cela créera des conflits

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 nous ignorons les conflits dans le clone et faisons plus de commits dans le dépôt d'origine maintenant,

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

Et puis nous faisons un git pull, nous obtenons

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'.

Notez que le filenow est dans un état non fusionné et si nous faisons un git status, nous pouvons clairement voir la même chose:

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

Donc, pour résoudre cela, nous devons d'abord résoudre le conflit de fusion que nous avons ignoré plus tôt

repo_clone $ vi file

et définissez son contenu sur

text2
text1
text1

puis ajoutez-le et validez les modifications

repo_clone $ git add file && git commit -m "resolved merge conflicts"
[master 39c3ba1] resolved merge conflicts
mu 無
la source
1
Pour être complet, j'ajouterais la réponse de @ Pawan pour utiliser 'git mergetool' pour résoudre les conflits. L'avant-dernière étape peut ne pas être très pratique («résoudre la fusion ... [en définissant] ... son contenu sur: [un texte]»).
undeniablyrob
Vous pouvez également fusionner en utilisant les conseils de @ user261. Quoi qu'il en soit, je pense que l'ajout d'une étape sur la façon de fusionner dans un sens pratique compléterait cette réponse.
undeniablyrob
3
Cette réponse fonctionne très bien lorsque vous avez des conflits simples à résoudre sur des fichiers uniques. Par exemple, une ou deux lignes de code différentes. Si vous avez plusieurs fichiers qui ont été fortement modifiés, c'est une solution difficile. Mais cela fait ressortir l'idée qu'avec Git, vous devriez vous engager souvent pour éviter les conflits difficiles.
Vaughn
46

Vous essayez d'ajouter un autre nouveau commit dans votre branche locale alors que votre répertoire de travail n'est pas propre. En conséquence, Git refuse de faire le pull. Considérez les diagrammes suivants pour mieux visualiser le scénario:

remote: A <- B <- C <- D
local: A <- B *
(* indique que vous avez plusieurs fichiers qui ont été modifiés mais non validés.)

Il existe deux options pour faire face à cette situation. Vous pouvez soit annuler les modifications apportées à vos fichiers, soit les conserver.

Première option: supprimer les modifications
Vous pouvez soit utiliser git checkoutpour chaque fichier non fusionné, soit vous pouvez utiliser git reset --hard HEADpour réinitialiser tous les fichiers de votre branche sur HEAD. À propos, HEAD dans votre succursale locale est B, sans astérisque. Si vous choisissez cette option, le diagramme devient:

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

Maintenant, lorsque vous tirez, vous pouvez avancer rapidement votre branche avec les modifications de master. Après avoir tiré, votre branche ressemblerait à master:

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

Option 2: conserver les modifications
Si vous souhaitez conserver les modifications, vous souhaiterez d'abord résoudre les conflits de fusion dans chacun des fichiers. Vous pouvez ouvrir chaque fichier dans votre IDE et rechercher les symboles suivants:

<<<<<<< HEAD
// votre version du code
=======
// la version de la télécommande du code
>>>>>>>

Git vous présente deux versions de code. Le code contenu dans les marqueurs HEAD est la version de votre succursale locale actuelle. L'autre version est ce qui vient de la télécommande. Une fois que vous avez choisi une version du code (et supprimé l'autre code ainsi que les marqueurs), vous pouvez ajouter chaque fichier à votre zone de préparation en tapant git add. La dernière étape consiste à valider votre résultat en tapant git commit -m avec un message approprié. À ce stade, notre diagramme ressemble à ceci:

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

Ici, j'ai étiqueté le commit que nous venons de faire comme C 'car il est différent du commit C sur la télécommande. Maintenant, si vous essayez de tirer, vous obtiendrez une erreur d'avance non rapide. Git ne peut pas lire les modifications dans remote sur votre branche, car votre branche et la télécommande ont divergé du commit ancêtre commun B.À ce stade, si vous voulez tirer, vous pouvez en faire un autre git merge, ou git rebasevotre branche sur la télécommande.

Maîtriser Git nécessite d'être capable de comprendre et de manipuler des listes liées unidirectionnelles. J'espère que cette explication vous fera réfléchir dans la bonne direction sur l'utilisation de Git.

Tim Biegeleisen
la source
33

Theres une solution simple à cela. Mais pour cela, vous devrez d'abord apprendre ce qui suit

vimdiff

Pour supprimer les conflits, vous pouvez utiliser

git mergetool

La commande ci-dessus ouvre essentiellement un fichier local, un fichier mixte, un fichier distant (3 fichiers au total), pour chaque fichier en conflit. Les fichiers locaux et distants sont juste pour votre référence, et en les utilisant, vous pouvez choisir ce qu'il faut inclure (ou non) dans le fichier mixte. Et il suffit de sauvegarder et de quitter le fichier.

Pawan Seerwani
la source
2
Je dirais que vimdiff n'est pas nécessaire (vous pouvez utiliser n'importe quel outil de fusion / différence de votre choix, tel que WinMerge, ou FileMerge intégré à OSX, etc.). Cela dit, c'est un excellent ajout à la réponse de @ mu.
undeniablyrob
32

Si vous ne souhaitez pas fusionner les modifications et que vous souhaitez toujours mettre à jour votre local, exécutez:

git reset --hard HEAD  

Cela réinitialisera votre local avec HEAD, puis tirera votre télécommande en utilisant git pull.

Si vous avez déjà validé votre fusion localement (mais que vous n'avez pas encore poussé vers Remote) et que vous souhaitez également la rétablir:

git reset --hard HEAD~1 
Santosh
la source
7

Si vous souhaitez extraire une branche distante pour l'exécuter localement (par exemple à des fins de révision ou de test), et lorsque $ git pullvous obtenez des conflits de fusion locaux:

$ 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
la source
5

Vous avez des fichiers localement qui doivent être fusionnés avant de pouvoir les extraire. Vous pouvez extraire les fichiers, puis tirer pour écraser vos fichiers locaux.

git checkout app/config/app.php app/config/database.php app/routes.php
git pull origin master
pseudo
la source
La fusion combine le contenu de deux fichiers. Actuellement, vos fichiers locaux diffèrent de ceux du serveur distant. La fusion doit être effectuée sur le serveur distant. Donc, si vous mettez en scène vos fichiers modifiés et les poussez, vos modifications seront ajoutées aux fichiers du référentiel. Ensuite, vos fichiers seront synchronisés et vous pourrez extraire l'intégralité du projet avec d'autres modifications. J'ai trouvé le livre d'aide de git très utile lorsque j'ai commencé à utiliser git. Vous pouvez le trouver ici: git-scm.com/book/en/Getting-Started
Nick
Notez que je ne suis pas l'OP. «Fusionner des fichiers» est une terminologie incorrecte. À proprement parler, vous fusionnez des commits, pas des fichiers.
jub0bs
Ah oui c'est vrai, mes apologie. J'essayais de donner une réponse simple
Nick
Eh bien, si vous avez des conflits lors de la fusion d'un commit, alors oui, vous aurez des fichiers conflictuels non fusionnés et vous devrez les fusionner.
Edward Thomson
3

Étapes à suivre :

step-1 : git reset --hard HEAD  (if you want to reset it to head)
step-2 : git checkout Master 
step-3 : git branch -D <branch Name>
(Remote Branch name where you want to get pull) 
step-4 : git checkout <branch name>
step-5 : git pull. (now you will not get any
error)

Merci, Sarbasish

Sarbasish Mishra
la source
2

Il y avait le même problème avec moi
Dans mon cas, les étapes sont les suivantes:

  1. Suppression de tous les fichiers commençant par le symbole U (non fusionné) . comme-

U   project/app/pages/file1/file.ts
U   project/www/assets/file1/file-name.html
  1. Extraire le code du maître

$ git pull origin master
  1. Vérifié le statut

 $ git status

Voici le message qui est apparu -
et ont respectivement 2 et 1 commit différent. Vous avez des chemins non fusionnés.
(use "git pull" to merge the remote branch into yours)

(fix conflicts and run "git commit")

Chemins non fusionnés:
(utilisez "git add ..." pour marquer la résolution)

both modified:   project/app/pages/file1/file.ts
both modified:   project/www/assets/file1/file-name.html
  1. Ajout de tous les nouveaux changements -

    $ git add project/app/pages/file1/file.ts
project/www/assets/file1/file-name.html
  1. Commettre des changements sur la tête

$ git commit -am "resolved conflict of the app."
  1. Poussé le code -

$ git push origin master

Quel tour peut poser problème résolu avec cette image - entrez la description de l'image ici

S.Yadav
la source
1

Lorsqu'un conflit de fusion se produit, vous pouvez ouvrir un fichier individuel. Vous obtiendrez des symboles "<<<<<<< ou >>>>>>>". Celles-ci font référence à vos modifications et aux modifications présentes sur la télécommande. Vous pouvez modifier manuellement la pièce requise. après cela, enregistrez le fichier puis faites: git add

Les conflits de fusion seront résolus.

dfordevy
la source
-1

Exécutez simplement cette commande:

git reset --hard
Grace Green
la source
3
Vous devriez expliquer ce que fait la commande, car certaines personnes seront très déçues si elles essaient de découvrir qu'elle a supprimé toutes leurs modifications locales actuelles: /
Joseph Budin
Cela fonctionne si vous copiez simplement vos modifications vers une source temporaire externe. Si vous n'avez que quelques fichiers, par exemple des fichiers de configuration pour un projet, c'est parfait. Exécutez la commande, puis annulez vos modifications. Travaille pour moi!
cwiggo