Question 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?


4123
2017-10-02 11:31


origine


Réponses:


Essayer: git mergetool

Il ouvre une interface graphique qui vous guide à travers chaque conflit et vous permet de choisir comment fusionner. Parfois, cela demande un peu de retouche manuelle, mais généralement c'est suffisant. C'est beaucoup mieux que de tout faire à la main certainement.

Selon le commentaire de @JoshGlover:

La commande n'ouvre pas nécessairement une interface graphique sauf si vous en installez une. Fonctionnement git mergetool pour moi a abouti à vimdiff utilisé. Vous pouvez installer l'un des outils suivants pour l'utiliser à la place: meld, opendiff, kdiff3, tkdiff, xxdiff, tortoisemerge, gvimdiff, diffuse, ecmerge, p4merge, araxis, vimdiff, emerge.

Voici l'exemple de procédure à utiliser vimdiff pour résoudre les conflits de fusion. Basé sur 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

Ceci définira vimdiff comme l'outil de fusion par défaut.

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

git mergetool

Étape 3: Vous verrez un affichage vimdiff au format suivant

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

Ces 4 vues sont

LOCAL - c'est un fichier de la branche actuelle

BASE - ancêtre commun, comment le fichier a regardé avant les deux changements

REMOTE - fichier que vous fusionnez dans votre branche

Fusionné - fusionner résultat, c'est ce qui est enregistré dans le repo

Vous pouvez naviguer parmi ces vues en utilisant ctrl+w. Vous pouvez accéder directement à la vue MERGED en utilisant ctrl+w suivi par j.

Plus d'infos sur vimdiff navigation ici et ici

Étape 4. Vous pouvez modifier la vue MERGED de la manière suivante

Si vous voulez obtenir des modifications de REMOTE

:diffg RE  

Si vous souhaitez obtenir des modifications de BASE

:diffg BA  

Si vous voulez obtenir des changements de LOCAL

:diffg LO 

Étape 5. Enregistrer, quitter, valider et nettoyer

:wqa enregistrer et quitter vi

git commit -m "message"

git clean Supprimez les fichiers supplémentaires (par exemple * .orig) créés par l'outil diff.


2415
2017-10-02 17:50



Voici un cas d'utilisation probable, à partir du haut:

Vous allez apporter quelques modifications, mais oups, vous n'êtes pas à jour:

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 obtenez à jour et essayez à nouveau, mais 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 décidez de regarder les changements:

git mergetool

Oh moi, oh mon dieu, en 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 nous essayons une dernière fois

git pull origin master

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

Ta-da!


1607
2017-08-04 17:04



Je trouve que les outils de fusion m'aident rarement à comprendre le conflit ou la résolution. J'ai généralement plus de succès en regardant les marqueurs de conflit dans un éditeur de texte et en utilisant git log comme un complément.

Voici quelques conseils:

Astuce un

La meilleure chose que j'ai trouvée est d'utiliser le style de conflit de fusion "diff3":

git config merge.conflictstyle diff3

Cela produit des marqueurs de conflit comme celui-ci:

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

La section du milieu est ce à quoi l'ancêtre commun ressemblait. Ceci est utile car vous pouvez le comparer aux versions supérieure et inférieure pour avoir une meilleure idée de ce qui a été changé dans chaque branche, ce qui vous donne une meilleure idée de l'objectif de chaque changement.

Si le conflit n'est que de quelques lignes, cela rend généralement le conflit très évident. (Savoir comment résoudre un conflit est très différent, vous devez être conscient de ce que les autres personnes travaillent.) Si vous êtes confus, il est probablement préférable de simplement appeler cette personne dans votre chambre afin qu'ils puissent voir ce que vous cherchez. à.)

Si le conflit est plus long, je vais couper et coller chacune des trois sections dans trois fichiers distincts, tels que «mien», «commun» et «le leur».

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

diff common mine
diff common theirs

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

Astuce Deux

Quelqu'un a déjà mentionné cela, mais comprendre l'intention derrière chaque différend est généralement très utile pour comprendre d'où vient un conflit et comment le gérer.

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

Cela montre tous les commits qui ont touché ce fichier entre l'ancêtre commun et les deux têtes que vous fusionnez. (Cela n'inclut donc pas les validations qui existent déjà dans les deux branches avant la fusion.) Cela vous aide à 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, exécutez ceux-ci. Si tu as un peluche, exécutez ça. S'il s'agit d'un projet pouvant être construit, construisez-le avant de le valider, etc. Dans tous les cas, vous devez faire un peu de test pour vous assurer que vos modifications n'ont rien brisé. (Heck, même une fusion sans conflit peut casser le code de travail.)

Astuce Quatre

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

Planifier à l'avance et être au courant de ce que les autres travaillent peuvent aider à prévenir les conflits de fusion et / ou les aider à les résoudre plus tôt - alors que les détails sont encore frais à l'esprit.

Par exemple, si vous savez que vous et une autre personne travaillez sur un refactoring différent qui affectera le même ensemble de fichiers, vous devriez vous parler à l'avance et avoir une meilleure idée des types de changements que chacun d'entre vous fabrication. Vous pourriez économiser beaucoup de temps et d'efforts si vous effectuez les changements planifiés en série plutôt qu'en parallèle.

Pour les refactorings majeurs qui traversent une grande partie du code, vous devriez sérieusement envisager de travailler en série: tout le monde arrête de travailler sur cette zone du code pendant qu'une personne effectue le refactoring complet.

Si vous ne pouvez pas travailler en série (en raison de la pression du temps, peut-être), alors communiquer sur les conflits de fusion attendus au moins vous aide à résoudre les problèmes plus tôt alors que les détails sont encore frais à l'esprit. Par exemple, si un collègue effectue une série de commits perturbatrice au cours d'une période d'une semaine, vous pouvez choisir de fusionner / rebaser sur cette branche de collègues une ou deux fois par jour pendant cette semaine. De cette façon, si vous trouvez des conflits de fusion / rebase, vous pouvez les résoudre plus rapidement que si vous attendez quelques semaines pour tout fusionner en un seul gros morceau.

Astuce Cinq

Si vous n'êtes pas sûr d'une fusion, ne le forcez pas.

La fusion peut sembler écrasante, surtout lorsqu'il y a beaucoup de fichiers conflictuels et que les marqueurs de conflit couvrent des centaines de lignes. Souvent, lors de l'estimation de projets logiciels, nous n'incluons pas suffisamment de temps pour les éléments généraux, comme la gestion d'une fusion noueuse, ce qui fait que l'on ressent le besoin de passer plusieurs heures à disséquer chaque conflit.

À long terme, planifier à l'avance et savoir ce sur quoi les autres travaillent sont les meilleurs outils pour anticiper les conflits de fusion et vous préparer à les résoudre correctement en moins de temps.


683
2017-09-28 21:08



  1. Identifiez les fichiers en conflit (Git devrait vous le dire).

  2. Ouvrez chaque fichier et examinez les différences; Git les démarque. Espérons qu'il sera évident quelle version de chaque bloc à conserver. Vous devrez peut-être en discuter avec d'autres développeurs qui ont commis le code.

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

  4. Une fois que vous avez résolu tout conflits, faire git rebase --continue ou quelle que soit la commande Git a dit de faire quand vous avez terminé.


321
2017-10-02 12:41



Découvrez les réponses à la question Stack Overflow Abandonner une fusion dans Git, notamment La réponse de Charles Bailey qui montre comment voir les différentes versions du fichier avec des problèmes, par exemple,

# Common base version of the file.
git show :1:some_file.cpp

# 'Ours' version of the file.
git show :2:some_file.cpp

# 'Theirs' version of the file.
git show :3:some_file.cpp

97
2017-10-03 15:15



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

git CLI

Voici des étapes simples à faire lorsque vous entrez en conflit:

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

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

    • Pour accepter la version distante / autre, utilisez: git checkout --theirs path/file. Cela rejettera toutes les modifications locales que vous avez effectuées pour ce fichier.

    • Pour accepter local / notre version, utilisez: git checkout --ours path/file

      Cependant, vous devez faire attention, car les changements à distance que les conflits ont été fait pour une raison quelconque.

      En relation: Quel est le sens précis de "notre" et "leur" dans git?

    • Modifiez les fichiers en conflit manuellement et recherchez le bloc de code entre <<<<</>>>>> choisissez ensuite la version ci-dessus ou ci-dessous =====. Voir: Comment les conflits sont présentés.

    • Les conflits de chemin et de nom de fichier peuvent être résolus par git add/git rm.

  3. Enfin, passez en revue les fichiers prêts pour la validation en utilisant: git status.

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

  4. Si tous les conflits ont été résolus avec succès, validez les modifications en: git commit -a et pousser à distance comme d'habitude.

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

DiffMerge

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

Il peut représenter graphiquement les changements entre 3 fichiers et il permet la fusion automatique (quand il est sécuritaire de le faire) et un contrôle total sur l'édition du fichier résultant.

DiffMerge

Source de l'image: DiffMerge (Capture d'écran Linux)

Il suffit de le télécharger et de l'exécuter en tant que:

git mergetool -t diffmerge .

macOS

Sur macOS, vous pouvez installer via:

brew install caskroom/cask/brew-cask
brew cask install diffmerge

Et probablement (si non fourni) vous avez besoin de l'emballage supplémentaire simple suivant placé dans votre PATH (par ex. /usr/bin):

#!/bin/sh
DIFFMERGE_PATH=/Applications/DiffMerge.app
DIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMerge
exec ${DIFFMERGE_EXE} --nosplash "$@"

Ensuite, vous pouvez utiliser les raccourcis clavier suivants:

  • -Alt-Up/Vers le bas pour passer aux changements précédents / suivants.
  • -Alt-La gauche/Droite accepter le changement de gauche ou de droite

Alternativement, vous pouvez utiliser opendiff (partie de Xcode Tools) qui vous permet de fusionner deux fichiers ou répertoires pour créer un troisième fichier ou répertoire.


88
2017-08-05 14:29



Si vous faites de petits commits fréquents, commencez par regarder les commentaires de commit avec git log --merge. alors git diff vous montrera les conflits.

Pour les conflits qui impliquent plus de quelques lignes, il est plus facile de voir ce qui se passe dans un outil GUI externe. J'aime opendiff - Git supporte également vimdiff, gvimdiff, kdiff3, tkdiff, fusionner, xxdiff, sortir de la boîte et vous pouvez en installer d'autres: git config merge.tool "your.tool" va définir votre outil choisi, puis git mergetool après une fusion échouée vous montrera les différences dans le contexte.

Chaque fois que vous éditez un fichier pour résoudre un conflit, git add filename mettra à jour l'index et votre diff ne le montrera plus. Lorsque tous les conflits sont traités et que leurs fichiers ont été git add-ed, git commit achèvera votre fusion.


73
2017-10-02 16:11



Voir Comment les conflits sont présentés ou, dans Git, le git merge documentation pour comprendre ce que sont les marqueurs de conflit de fusion.

Également Comment résoudre les conflits section explique comment résoudre les conflits:

Après avoir vu un conflit, vous pouvez faire deux choses:

  • Décidez de ne pas fusionner. Les seuls nettoyages dont vous avez besoin sont de réinitialiser le fichier d'index au HEAD s'engager à inverser 2. et à nettoyer les changements d'arbre de travail effectués par 2. et 3.; git merge --abort peut être utilisé pour cela.

  • Résolvez les conflits. Git marquera les conflits dans l'arbre de travail. Editez les fichiers en forme et git add à l'index. Utilisation git commit pour sceller l'affaire.

Vous pouvez travailler à travers le conflit avec un certain nombre d'outils:

  • Utilisez un mergetool. git mergetool pour lancer un mergetool graphique qui vous aidera à traverser la fusion.

  • Regardez les diffs. git diff montrera un diff à trois voies, en soulignant les changements à la fois de la HEAD et MERGE_HEAD versions.

  • Regardez les diffs de chaque branche. git log --merge -p <path> montrera diffs d'abord pour le HEAD version, puis le MERGE_HEAD version.

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

Vous pouvez également lire sur les marqueurs de conflit de fusion et comment les résoudre dans le Pro Git section des livres Conflits de fusion de base.


43
2017-07-14 18:34