Comment résoudre les conflits de fusion dans git

Existe-t-il un bon moyen d’expliquer comment résoudre les conflits de fusion dans git?

4274
02 окт. Spoike mis 02 oct. 2008-10-02 14:31 '08 à 14h31 2008-10-02 14:31
@ 37 réponses
  • 1
  • 2

Essayez: git mergetool

Il ouvre l'interface graphique qui traverse chaque conflit, et vous pouvez choisir comment combiner. Cela nécessite parfois un peu de modification manuelle par la suite, mais généralement cela suffit. C'est beaucoup mieux que de tout faire manuellement.

Selon le commentaire de @JoshGlover:

La commande n'ouvre pas nécessairement l'interface graphique si vous ne l'installez pas. L'exécution de git mergetool pour moi a conduit à l'utilisation de vimdiff . Vous pouvez installer l’un des outils suivants pour l’utiliser à la place: opendiff , kdiff3 , tkdiff , xxdiff , xxdiff , tortoisemerge , gvimdiff , diffuse , ecmerge , p4merge , araxis , vimdiff , emerge .

Vous trouverez ci-dessous un exemple de procédure d'utilisation de vimdiff pour résoudre les conflits de fusion. Par ce lien

Étape 1 : Exécutez les commandes suivantes dans votre terminal

 git config merge.tool vimdiff git config merge.conflictstyle diff3 git config mergetool.prompt false 

Cela définira vimdiff comme outil de fusion par défaut.

Étape 2 : Exécutez la commande suivante dans le terminal

 git mergetool 

Étape 3 : Vous verrez un affichage vimdiff dans le format suivant.

  +----------------------+ | | | | |LOCAL |BASE |REMOTE | | | | | +----------------------+ | MERGED | | | +----------------------+ 

Ces 4 types

LOCAL est le fichier de la branche actuelle.

BASE - un ancêtre commun, à quoi ressemblait le fichier avant les deux modifications

REMOTE - un fichier que vous fusionnez dans votre branche

MERGED - le résultat de la fusion, c'est ce qui est stocké dans le repo

Vous pouvez naviguer entre ces vues à l'aide de ctrl+w accéder directement à la vue MERGED à l'aide de ctrl+w et j .

Plus d'informations sur la navigation vimdiff ici et ici.

Étape 4 Vous pouvez modifier MERGED comme suit.

Si vous souhaitez recevoir les modifications de REMOTE

 :diffg RE 

Si vous souhaitez recevoir les modifications de BASE

 :diffg BA 

Si vous souhaitez recevoir les modifications de LOCAL

 :diffg LO 

Étape 5 Enregistrer, quitter, verrouiller et effacer

:wqa enregistrer et quitter vi

git commit -m "message"

git clean Supprime les fichiers inutiles (par exemple, * .orig) créés par l'outil diff.

2535
02 окт. la réponse est donnée par Peter Burns le 02 oct. 2008-10-02 20:50 08 à 20h50 2008-10-02 20h50

Voici un précédent probable, d'en haut:

Vous allez faire quelques changements, mais malheureusement, vous ne savez pas:

 git fetch origin git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Updating a030c3a..ee25213 error: Entry 'filename.c' not uptodate. Cannot merge. 

Donc, vous mettez à jour et essayez à nouveau, mais vous avez un conflit:

 git add filename.c git commit -m "made some wild and crazy changes" git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Auto-merging filename.c CONFLICT (content): Merge conflict in filename.c Automatic merge failed; fix conflicts and then commit the result. 

Alors vous avez décidé de regarder les changements:

border=0
 git mergetool 

Oh, moi, oh, mon amont a changé certaines choses, mais juste pour utiliser mes changements ... non ... leurs changements ...

 git checkout --ours filename.c git checkout --theirs filename.c git add filename.c git commit -m "using theirs" 

Et puis on essaie la dernière fois.

 git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Already up-to-date. 

Ta-da!

1625
04 авг. la réponse est donnée par CoolAJ86 04 août. 2010-08-04 20:04 10h à 20h04: 2010-08-04 20:04

Je trouve que les outils de fusion m'aident rarement à comprendre le conflit ou la résolution. En général, je regarde plus efficacement les marqueurs de conflit dans un éditeur de texte et l’utilisation de git log comme complément.

Voici quelques astuces:

Premier conseil

Le mieux que j'ai trouvé est d'utiliser le style diff3 du conflit de fusion:

git config merge.conflictstyle diff3

Cela crée des marqueurs de conflit comme ceci:

 <<<<<<< Changes made on the branch that is being merged into. In most cases, this is the branch that I have currently checked out (ie HEAD). ||||||| The common ancestor version. ======= Changes made on the branch that is being merged in. This is often a feature/topic branch. >>>>>>> 

La partie centrale est à quoi ressemblait l'ancêtre commun. Cela est utile car vous pouvez le comparer aux versions supérieure et inférieure pour mieux comprendre ce qui a été modifié dans chaque branche, ce qui vous donne une meilleure idée de la raison d'être de chaque modification.

Si le conflit ne se compose que de quelques lignes, cela rend le conflit très évident. (Savoir résoudre un conflit est très différent: vous devez savoir sur quoi les autres personnes travaillent. En cas de confusion, il est préférable d’appeler cette personne dans votre chambre afin qu’elle puisse voir ce que vous recherchez.)

Si le conflit est plus long, je coupe et colle chacune des trois sections dans trois fichiers distincts, tels que «mine», «commun» et «eux».

Ensuite, je peux exécuter les commandes suivantes pour voir deux situations qui ont provoqué le conflit:

 diff common mine diff common theirs 

Ce n'est pas la même chose que d'utiliser l'outil de fusion, car l'outil de fusion inclura tous les diff-hunks non conflictuels. Je trouve cela distrayant.

Astuce deux

Quelqu'un en a déjà parlé, mais il est généralement utile de comprendre l’intention qui se cache derrière chaque diff. Mot est utile pour comprendre l’origine du conflit et savoir comment le gérer.

 git log --merge -p <name of file> 

Cela montre tous les commits concernant ce fichier entre un ancêtre commun et deux têtes que vous fusionnez. (Ainsi, cela n'inclut pas les commits qui existaient déjà dans les deux branches avant la fusion.) Cela permet d'ignorer les différences qui ne sont clairement pas un facteur dans votre conflit actuel.

Astuce trois

Vérifiez vos modifications avec des outils automatisés.

Si vous avez des tests automatisés, lancez-les. Si vous avez une charpie , lancez-la. S'il s'agit d'un projet de construction, vous devez le construire avant de le terminer, etc. Dans tous les cas, vous devez faire quelques tests pour vous assurer que vos modifications ne sont pas enfreintes. (Heck, même la fusion sans conflits peut casser le code de travail.)

Astuce quatre

Planifier à l'avance; communiquer avec des collègues.

La planification et la prise de conscience du bon fonctionnement des autres peuvent aider à prévenir les conflits de fusion et / ou à les résoudre plus tôt, alors que les détails sont toujours pertinents.

Par exemple, si vous savez que vous et une autre personne travaillez sur différentes refactorisations qui affecteront le même ensemble de fichiers, vous devez vous parler longtemps à l'avance et mieux comprendre les types de modifications que chacun de vous apporte. Vous pouvez économiser beaucoup de temps et d'efforts si vous effectuez les modifications planifiées à tour de rôle et non en parallèle.

Pour les grands refactorisations qui traversent un gros morceau de code, vous devriez sérieusement envisager de travailler en séquence: tout le monde cesse de travailler sur ce domaine de code et une personne effectue une refactorisation complète.

Si vous ne pouvez pas travailler de manière cohérente (peut-être à cause de pressions temporaires), le fait de parler des conflits de fusion attendus vous aidera au moins à résoudre les problèmes plus tôt, alors que les détails sont encore nouveaux. Par exemple, si un employé effectue une série de validations destructives en une semaine, vous pouvez fusionner / reconditionner cette branche une ou deux fois par jour cette semaine. Ainsi, si vous rencontrez des conflits de fusion / redirection, vous pouvez les résoudre plus rapidement que si vous attendez quelques semaines pour tout fusionner en un seul élément.

Astuce cinq

Si vous n'êtes pas sûr de la fusion, ne la forcez pas.

La fusion peut être fastidieuse, en particulier lorsque de nombreux fichiers sont en conflit, et que les marqueurs de conflit couvrent des centaines de lignes. Souvent, lors de l’évaluation de projets logiciels, nous ne prenons pas assez de temps pour les surtaxes, telles que le traitement d’une fusion insensée, ce qui donne l’impression que c’est une véritable résistance que de passer plusieurs heures à analyser chaque conflit.

À long terme, planifier et anticiper le travail des autres sont les meilleurs outils pour prédire les conflits de fusion et se préparer pour la bonne solution en moins de temps.

696
29 сент. La réponse est donnée par Mark E. Haase 29 sep. 2011-09-29 00:08 '11 à 0:08 2011-09-29 00:08
  • Déterminez quels fichiers sont en conflit (Git devrait vous le dire).

  • Ouvrez chaque fichier et découvrez les différences. Git les démarque. J'espère que la version de chaque bloc à conserver sera évidente. Vous devrez peut-être en discuter avec d'autres développeurs ayant terminé le code.

  • Une fois que vous avez résolu le conflit dans le fichier git add the_file , git add the_file .

  • Dès que vous résolvez tous les conflits, lancez git rebase --continue ou n’importe quelle commande que Git a dite lorsque vous avez terminé.

326
02 окт. la réponse est donnée davetron5000 02 oct. 2008-10-02 15:41 '08 à 15h41 2008-10-02 15:41

Vérifiez les réponses à la question Abort Git Cancellation , en particulier la réponse de Charles Bailey , qui montre comment afficher différentes versions d'un fichier problématique, par exemple

100
03 окт. Réponse donnée par Pat Notz le 03 octobre 2008-10-03 18:15 2008 à 18h15 2008-10-03 18:15

La fusion de conflit se produit lorsque des modifications sont apportées à un fichier en même temps. Voici comment le résoudre.

git CLI

Voici les étapes simples à suivre lorsque vous vous trouvez dans un état conflictuel:

  • Notez la liste des fichiers en conflit: git status (dans la section Unmerged paths ).
  • Résolvez les conflits séparément pour chaque fichier avec l'une des approches suivantes:

    • Utilisez l'interface graphique pour résoudre les conflits: git mergetool (le moyen le plus simple).

    • Pour accepter une version distante / autre, utilisez: git checkout --theirs path/file . Cela rejettera toute modification locale apportée à ce fichier.

    • Pour accepter la version locale / our, utilisez: git checkout --ours path/file

      Cependant, vous devez faire attention, car les modifications supprimées ont été éliminées pour une raison quelconque.

      Connexes: Quel est le sens exact de "our" et "them" dans git?

    • Editez les fichiers en conflit manuellement et localisez le bloc de code entre <<<<< / >>>>> , puis sélectionnez la version ci-dessus ou ci-dessous ===== . Voir: Comment les conflits sont présentés .

    • Les conflits de chemins et de noms de fichiers peuvent être résolus avec git add / git rm .

  • Enfin, examinez les fichiers prêts pour la validation en utilisant: git status .

    Si vous avez toujours des fichiers sous des Unmerged paths et que vous avez résolu le conflit manuellement, faites savoir à Git que vous l'avez résolu: git add path/file .

  • Si tous les conflits ont été résolus avec succès, copiez les modifications: git commit -a et cliquez sur celui supprimé, comme d'habitude.

Voir aussi: Résolution d'un conflit de fusion à partir de la ligne de commande dans GitHub

DiffMerge

J'ai utilisé avec succès DiffMerge , qui peut visuellement comparer et fusionner des fichiers sous Windows, MacOS et Linux / Unix.

Il affiche graphiquement les changements entre 3 fichiers et permet la fusion automatique (quand c'est sûr) et le contrôle total de l'édition du fichier résultant.

2019

05 авг. la réponse est donnée kenorb 05 août. 2015-08-05 17:29 '15 à 17:29 2015-08-05 17:29

Si vous effectuez de petits commits fréquents, commencez par afficher les commentaires de validation avec git log --merge . Ensuite, git diff vous montrera les conflits.

Pour les conflits impliquant plusieurs lignes, il est plus facile de voir ce qui se passe dans l'outil d'interface graphique externe. J'aime opendiff - Git prend également en charge vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, sortent des sentiers battus et vous pouvez en installer d'autres: git config merge.tool "your.tool" installera votre outil choisi, puis git mergetool après échec La fusion vous montrera les différences de contexte.

Chaque fois que vous éditez un fichier pour résoudre un conflit, git add filename met à jour l'index et votre diff ne l'affiche plus. Lorsque tous les conflits ont été traités et que leurs fichiers ont été git add git commit , git commit complétera la fusion.

75
02 окт. la réponse est donnée par Paul le 02 octobre 2008-10-02 19:11 '08 à 19h11 2008-10-02 19:11

Reportez-vous à la section Présentation des conflits ou dans Git, la documentation relative à la git merge , pour comprendre ce que sont les marqueurs de conflit.

De plus, la section Comment résoudre les conflits explique comment résoudre les conflits:

Après avoir visualisé le conflit, vous pouvez faire deux choses:

  • Décidez de ne pas fusionner. Les seuls nettoyants dont vous avez besoin sont un fichier d'index de réinitialisation permettant de fixer le HEAD pour la transformation 2. inverse et de supprimer le village en activité. Les modifications apportées aux points 2. et 3; git merge --abort peut être utilisé pour cela.

  • Résoudre les conflits. Git marquera les conflits dans l’arbre de travail. Editez les fichiers du formulaire et git add les à l’index. Utilisez git commit pour sceller un accord.

Vous pouvez travailler en conflit avec plusieurs outils:

  • Utilisez mergetool. git mergetool pour exécuter un outil de fusion graphique qui fonctionnera lors d'une fusion.

  • Regardez les différences. git diff affiche un git diff trois côtés, soulignant les modifications des versions HEAD et MERGE_HEAD .

  • Regardez les différences entre chaque branche. git log --merge -p <path> affichera d'abord diff pour la version HEAD , puis la version MERGE_HEAD .

  • Regardez les originaux. git show :1:filename indique l'ancêtre commun, git show :2:filename indique la version de HEAD et git show :3:filename indique la version de MERGE_HEAD .

Vous pouvez également en savoir plus sur la marque du conflit de fusion et sur la façon de les résoudre dans la section Conflits de fusion principaux de Pro Git .

43
14 июля '13 в 21:34 2013-07-14 21:34 la réponse est donnée par user456814 Le 14 juillet '13 à 21:34 2013-07-14 21:34

Pour Emacs, les utilisateurs souhaitant résoudre des conflits de fusion semi-manuels:

 git diff --name-status --diff-filter=U 

Affiche tous les fichiers nécessitant une résolution de conflit.

Ouvrez chacun de ces fichiers un par un ou tous à la fois:

 emacs $(git diff --name-only --diff-filter=U) 

Lors de la visite d’un tampon nécessitant une édition dans Emacs, entrez

 ALT+x vc-resolve-conflicts 

Cela ouvrira les trois tampons (le mien, eux et le tampon de sortie). Naviguez en appuyant sur "n" (zone suivante), "p" (zone de prédiction). Appuyez sur "a" et "b" pour copier ma ou votre région dans le tampon de sortie, respectivement. Et / ou éditez directement le tampon de sortie.

Lorsque vous avez terminé: appuyez sur "q". Emacs vous demande si vous voulez sauvegarder ce tampon: oui. Une fois la mémoire tampon terminée, marquez-la comme résolue au lancement par le lanceur:

 git add FILENAME 

Ayant fini de travailler avec tous les types de tampons

 git commit 

pour compléter la fusion.

36
23 февр. la réponse est donnée eci le 23 février 2013-02-23 02:04 '13 à 2:04 2013-02-23 02:04

Je veux soit ma version ou leur version complètement, soit je veux voir les modifications individuelles et prendre une décision pour chacune d’elles.

Accepter pleinement ma ou leur version :

Accepter ma version (locale, notre):

 git checkout --ours -- <filename> git add <filename> # Marks conflict as resolved git commit -m "merged bla bla" # An "empty" commit 

Accepter leur version (les supprimer):

 git checkout --theirs -- <filename> git add <filename> git commit -m "merged bla bla" 

Si vous voulez faire pour tous les fichiers en conflit, exécutez:

 git merge --strategy-option ours 

ou

 git merge --strategy-option theirs 

Passez en revue toutes les modifications et acceptez-les individuellement.

  1. git mergetool
  2. Passez en revue les modifications et acceptez toute version pour chacune d’elles.
  3. git add <filename>
  4. git commit -m "merged bla bla"

Par défaut, mergetool fonctionne sur la ligne de commande . L'utilisation de la ligne de commande mergetool doit faire l'objet d'un problème distinct.

Vous pouvez également installer un outil visuel pour cela, par exemple meld et exécuter

 git mergetool -t meld 

La version locale (notre), "de base" ou "unifiée" (le résultat actuel de la fusion) et la ou les télécommande (s) seront ouvertes. Enregistrez la version fusionnée lorsque vous avez terminé, exécutez à nouveau git mergetool -t meld jusqu'à ce que vous obteniez le git mergetool -t meld "Pas besoin de fusionner des fichiers", puis passez aux étapes 3 et 4.

28
29 сент. La réponse est donnée par Noidea 29 sep . 2016-09-29 16:02 '16 à 16:02 2016-09-29 16:02

Veuillez compléter les étapes suivantes pour résoudre les conflits de fusion dans git:

  1. Vérifier le statut Git : Statut Git

  2. Obtenir le jeu de correctifs: git fetch (vérifiez le correct correctif dans votre commit git )

  3. Extrait de la branche locale (dans mon exemple, temp1): git checkout -b temp1

  4. Extraire le contenu récent du maître: git pull --rebase origin master

  5. Exécutez mergetool, vérifiez les conflits et corrigez-les ... et vérifiez les modifications dans la branche distante avec votre branche actuelle: git mergetool

  6. Vérifier à nouveau le statut: statut git

  7. Supprimez les fichiers inutiles créés localement avec mergetool; généralement, mergetool crée un fichier supplémentaire portant l'extension * .orig. Supprimez ce fichier car il ne s'agit que d'une copie, corrigez les modifications localement et ajoutez la version correcte de vos fichiers. git add #your_changed_correct_files

  8. Vérifier à nouveau le statut: statut git

  9. Validez les modifications sur le même identifiant (vous éviterez ainsi un nouvel ensemble de correctifs): git commit --amend

  10. Push to master branch: git push (vers votre référentiel Git)

28
16 апр. La réponse est donnée à Chhabilal le 16 avril . 2015-04-16 10:02 '15 à 10:02 2015-04-16 10:02

En termes simples, si vous savez bien que les modifications dans l'un des référentiels ne sont pas importantes et que vous souhaitez autoriser toutes les modifications en faveur de l'autre, utilisez:

 git checkout . --ours 

autoriser des modifications en faveur de votre référentiel , ou

 git checkout . --theirs 

permettre des changements en faveur d' un autre ou d'un référentiel principal .

Ou vous devrez utiliser l'outil de fusion d'interface graphique pour parcourir les fichiers, par exemple l' p4merge fusion de p4merge , ou écrire tout nom que vous avez déjà défini.

 git mergetool -t p4merge 

et après avoir terminé le fichier, vous devrez sauvegarder et fermer pour ouvrir le suivant.

27
26 янв. Répondu par Mohamed Selim le 26 janvier 2016-01-26 20:42 '16 à 20:42 pm 2016-01-26 20:42

Vous pouvez résoudre les conflits de fusion de plusieurs manières, comme d'autres l'ont détaillé.

Je pense que la vraie clé est de savoir comment les changements se produisent avec les référentiels locaux et distants. La clé est la compréhension des branches de suivi. J'ai découvert que je considérais la branche de suivi comme la «partie manquante au milieu» entre moi, mon répertoire de fichiers local et réel et la télécommande, définie comme étant l'origine.

Personnellement, je me suis habitué à deux choses pour éviter cela.

Au lieu de:

 git add . git commit -m"some msg" 

Ce qui a deux inconvénients -

a) Tous les fichiers nouveaux / modifiés sont ajoutés et peuvent contenir des modifications indésirables.
b) Vous ne pouvez pas d'abord voir la liste des fichiers.

Alors à la place:

 git add file,file2,file3... git commit # Then type the files in the editor and save-quit. 

De cette façon, vous discuterez plus délibérément des fichiers qui sont ajoutés, et vous pouvez également faire défiler la liste et réfléchir un peu plus à l'aide de l'éditeur du message. Je trouve que cela améliore également mes messages de commit lorsque j'utilise l'éditeur en plein écran, plutôt que l'option -m .

[Mise à jour - au fil du temps, je suis passé de plus en plus à:

 git status # Make sure I know whats going on git add . git commit # Then use the editor 

]

Aussi (et plus précisément pour votre situation), j'essaie d'éviter:

 git pull 

ou

 git pull origin master.