Comment résoudre les conflits de fusion dans Git?
git
installation par défaut . J'ai réussi à accéder à la page de démarrage SE pour moi aujourd'hui, 2017, avec 1,3 million de vues et des milliers de votes dans les deux sens. Fascinant.
Comment résoudre les conflits de fusion dans Git?
git
installation par défaut . J'ai réussi à accéder à la page de démarrage SE pour moi aujourd'hui, 2017, avec 1,3 million de vues et des milliers de votes dans les deux sens. Fascinant.
Réponses:
Essayer: git mergetool
Il ouvre une interface graphique qui vous guide à travers chaque conflit, et vous pouvez choisir comment fusionner. Parfois, cela nécessite un peu de retouche manuelle par la suite, mais généralement c'est suffisant en soi. C'est bien mieux que de faire le tout à la main certainement.
Selon le commentaire de @JoshGlover:
La commande
n'ouvre pas nécessairement une interface graphique, sauf si vous en installez une. Courir
git mergetool
pour moi avimdiff
été 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
Cela définira vimdiff comme 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 courante
BASE - ancêtre commun, à quoi ressemblait le fichier avant les deux changements
REMOTE - fichier que vous fusionnez dans votre branche
FUSION - résultat de la fusion, c'est ce qui est enregistré dans le référentiel
Vous pouvez naviguer parmi ces vues à l'aide de ctrl+ w. Vous pouvez accéder directement à la vue FUSION avec ctrl+ wsuivi de j.
Plus d'informations sur la navigation vimdiff ici et ici
Étape 4 . Vous pouvez modifier la vue fusionnée de la manière suivante
Si vous souhaitez obtenir des modifications de REMOTE
:diffg RE
Si vous souhaitez obtenir des modifications de BASE
:diffg BA
Si vous souhaitez obtenir des modifications 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.
git mergetool -y
pour enregistrer quelques frappes si vous fusionnez un grand nombre de fichiers à la fois.
git mergetool
pour moi a vimdiff
été 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
.
git mergetool -t bc3
).
Voici un cas d'utilisation probable, d'en haut:
Vous allez apporter quelques changements, 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.
Vous vous mettez à jour et réessayez, 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.
Vous décidez donc de jeter un œil aux changements:
git mergetool
Oh mon, oh mon, en amont 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 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!
git merge --help
this question
Je trouve que les outils de fusion m'aident rarement à comprendre le conflit ou la résolution. Je réussis généralement mieux à regarder les marqueurs de conflit dans un éditeur de texte et à utiliser git log comme supplément.
Voici quelques conseils:
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 à quoi ressemblait l'ancêtre commun. 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é modifié sur chaque branche, ce qui vous donne une meilleure idée de l'objectif de chaque modification.
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 savoir sur quoi travaillent les autres. Si vous êtes confus, il est probablement préférable d'appeler cette personne dans votre chambre pour qu'elle puisse 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 "le mien", "commun" et "le leur".
Ensuite, je peux exécuter les commandes suivantes pour voir les deux mecs diff 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 comprendra également tous les morceaux de diff non conflictuels. Je trouve cela distrayant.
Quelqu'un l'a déjà mentionné, mais comprendre l'intention derrière chaque morceau diff 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. (Il n'inclut donc pas les validations qui existent déjà dans les deux branches avant la fusion.) Cela vous aide à ignorer les morceaux différents qui ne sont clairement pas un facteur dans votre conflit actuel.
Vérifiez vos modifications avec des outils automatisés.
Si vous avez des tests automatisés, exécutez-les. Si vous avez des peluches , lancez-le. Si c'est un projet à construire, alors construisez-le avant de vous engager, etc. Dans tous les cas, vous devez faire un peu de test pour vous assurer que vos modifications n'ont rien cassé. (Heck, même une fusion sans conflits peut casser le code de travail.)
Planifier à l'avance; communiquer avec des collègues.
Planifier à l'avance et être conscient de ce sur quoi les autres travaillent peut aider à prévenir les conflits de fusion et / ou à 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 tous les deux sur une refactorisation différente qui affectera à la fois le même ensemble de fichiers, vous devriez vous parler à l'avance et avoir une meilleure idée des types de changements que chacun de vous est fabrication. Vous pourriez économiser beaucoup de temps et d'efforts si vous effectuez les changements prévus en série plutôt qu'en parallèle.
Pour les remaniements majeurs qui traversent une large bande de code, vous devriez fortement 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 contraintes de temps, peut-être), alors communiquer sur les conflits de fusion attendus vous aide au moins à résoudre les problèmes plus tôt tandis que les détails sont encore frais à l'esprit. Par exemple, si un collègue effectue une série de commissions perturbatrices 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.
Si vous n'êtes pas sûr d'une fusion, ne la forcez pas.
La fusion peut sembler écrasante, surtout lorsqu'il y a beaucoup de fichiers en conflit et que les marqueurs de conflit couvrent des centaines de lignes. Souvent, lorsque nous estimons des projets logiciels, nous n'incluons pas suffisamment de temps pour les éléments de surcharge tels que la gestion d'une fusion noueuse, donc cela ressemble à un vrai frein de passer plusieurs heures à disséquer chaque conflit.
À long terme, planifier à l'avance et être conscient de 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.
p4merge
, qui peut être installé et utilisé séparément des autres outils de Perforce (dont je n'ai pas utilisé, mais dont j'ai entendu des plaintes).
git config merge.conflictstyle diff3
- Merci Monsieur. C'est incroyable et cela m'a libéré d'essayer de trouver (et de payer $$) pour une bonne interface graphique de fusion à 3 voies. IMO, c'est mieux car il montre l'ancêtre commun ainsi que local / distant et affiche les dernières lignes de journal de validation que (AFAIK) aucune interface graphique ne fait. Les commits vous aident certainement à identifier quel code appartient à quelle branche.
Identifiez les fichiers en conflit (Git devrait vous le dire).
Ouvrez chaque fichier et examinez les différences; Git les délimite. Avec un peu de chance, il sera évident quelle version de chaque bloc conserver. Vous devrez peut-être en discuter avec d'autres développeurs qui ont validé le code.
Une fois que vous avez résolu le conflit dans un fichier git add the_file
.
Une fois que vous avez résolu tous les conflits, exécutez git rebase --continue
ou n'importe quelle commande que Git a dit de faire lorsque vous avez terminé.
git add
met en scène les fichiers dans l'index; il ne pas ajouter quoi que ce soit au dépôt. git commit
ajoute des éléments au référentiel. Cette utilisation est logique pour les fusions - la fusion met automatiquement en scène toutes les modifications qui peuvent être fusionnées automatiquement; il vous appartient de fusionner les autres modifications et de les ajouter à l'index lorsque vous avez terminé.
Consultez les réponses à la question Stack Overflow Abandonner une fusion dans Git , en particulier la réponse de Charles Bailey qui montre comment afficher 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
Les conflits de fusion se produisent lorsque des modifications sont apportées à un fichier en même temps. Voici comment le résoudre.
git
CLIVoici les étapes simples que faire lorsque vous êtes en conflit:
git status
(sous la Unmerged paths
section).Résolvez les conflits séparément pour chaque fichier par l'une des approches suivantes:
Utilisez l'interface graphique pour résoudre les conflits: git mergetool
(la manière la plus simple).
Pour accepter à distance / autre version, utilisez: git checkout --theirs path/file
. Cela rejettera toutes les modifications locales que vous avez apportées à ce fichier.
Pour accepter la version locale / notre version, utilisez: git checkout --ours path/file
Cependant, vous devez être prudent, car les modifications à distance que les conflits ont été faites pour une raison quelconque.
Connexes: Quelle est la signification précise de "nôtre" et "leur" dans git?
Modifiez les fichiers en conflit manuellement et recherchez le bloc de code entre <<<<<
/ >>>>>
puis choisissez 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
.
Enfin, passez en revue les fichiers prêts à être validés en utilisant: git status
.
Si vous avez encore des fichiers sous Unmerged paths
et que vous avez résolu le conflit manuellement, faites savoir à Git que vous l'avez résolu en:git add path/file
.
Si tous les conflits ont été résolus avec succès, validez les modifications en: git commit -a
et poussez sur remote comme d'habitude.
Voir également: Résolution d'un conflit de fusion à partir de la ligne de commande sur GitHub
Pour un didacticiel pratique, consultez: Scénario 5 - Résolution des conflits de fusion par Katacoda .
J'ai utilisé avec succès DiffMerge qui peut comparer visuellement et fusionner des fichiers sur Windows, macOS et Linux / Unix.
Il peut représenter graphiquement les changements entre 3 fichiers et il permet une fusion automatique (lorsque cela est sûr) et un contrôle total sur l'édition du fichier résultant.
Source de l'image: DiffMerge (capture d'écran Linux)
Il suffit de le télécharger et de l'exécuter dans le référentiel en tant que:
git mergetool -t diffmerge .
Sur macOS, vous pouvez installer via:
brew install caskroom/cask/brew-cask
brew cask install diffmerge
Et probablement (si non fourni) vous avez besoin du wrapper extra simple suivant placé dans votre PATH (par exemple /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:
Alternativement, vous pouvez utiliser opendiff (qui fait partie des outils Xcode) qui vous permet de fusionner deux fichiers ou répertoires ensemble pour créer un troisième fichier ou répertoire.
Si vous effectuez fréquemment de petites validations, commencez par regarder les commentaires de validation avec git log --merge
. Ensuite git diff
, vous montrera les conflits.
Pour les conflits qui impliquent plusieurs lignes, il est plus facile de voir ce qui se passe dans un outil GUI externe. J'aime opendiff - Git prend également en charge vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, sortent de la boîte et vous pouvez en installer d'autres: git config merge.tool "your.tool"
définira l'outil choisi, puisgit mergetool
après une fusion échouée, vous montrera les différences dans le contexte.
Chaque fois que vous modifiez un fichier pour résoudre un conflit, git add filename
mettra à jour l'index et votre diff ne l'affichera plus. Lorsque tous les conflits seront traités et que leurs fichiers auront été git add
supprimés, git commit
la fusion sera terminée.
Voir Comment les conflits sont présentés ou, dans Git, la git merge
documentation pour comprendre ce que sont les marqueurs de conflit de fusion.
De plus, la section Comment résoudre les conflits 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
commit pour inverser 2. et de nettoyer les modifications de l'arborescence de travail effectuées par 2. et 3 .;git merge --abort
peut être utilisé pour cela.Résolvez les conflits. Git marquera les conflits dans l'arborescence de travail. Modifiez les fichiers en forme et
git add
les indexer. Utilisezgit commit
pour sceller l'accord.Vous pouvez résoudre le conflit avec un certain nombre d'outils:
Utilisez un mergetool.
git mergetool
pour lancer un mergetool graphique qui vous aidera tout au long de la fusion.Regardez les différences.
git diff
affichera un diff à trois voies, mettant en évidence les changements à la fois des versionsHEAD
etMERGE_HEAD
.Regardez les différences de chaque branche.
git log --merge -p <path>
affichera d'abord les différences pour laHEAD
version, puis laMERGE_HEAD
version.Regardez les originaux.
git show :1:filename
affiche l'ancêtre commun,git show :2:filename
affiche laHEAD
version etgit show :3:filename
affiche laMERGE_HEAD
version.
Vous pouvez également lire sur les marqueurs de conflit de fusion et comment les résoudre dans la section du livre Pro Git Conflits de fusion de base .
Je veux soit ma ou leur version complète, soit je veux examiner les modifications individuelles et décider pour chacune d'entre elles.
Accepter entièrement ma ou leur version :
Acceptez ma version (locale, la nôtre):
git checkout --ours -- <filename>
git add <filename> # Marks conflict as resolved
git commit -m "merged bla bla" # An "empty" commit
Acceptez leur version (à distance, la leur):
git checkout --theirs -- <filename>
git add <filename>
git commit -m "merged bla bla"
Si vous souhaitez exécuter tous les fichiers de conflit, exécutez:
git merge --strategy-option ours
ou
git merge --strategy-option theirs
Passez en revue toutes les modifications et acceptez-les individuellement
git mergetool
git add <filename>
git commit -m "merged bla bla"
La valeur par défaut mergetool
fonctionne en ligne de commande . Comment utiliser un mergetool en ligne de commande devrait être une question distincte.
Vous pouvez également installer un outil visuel pour cela, par exemple meld
et exécuter
git mergetool -t meld
Il ouvrira la version locale (la nôtre), la version "de base" ou "fusionnée" (le résultat actuel de la fusion) et la version distante (la leur). Enregistrez la version fusionnée lorsque vous avez terminé, exécutez à git mergetool -t meld
nouveau jusqu'à ce que vous obteniez «Aucun fichier n'a besoin d'être fusionné», puis passez aux étapes 3. et 4.
Pour les utilisateurs d' Emacs qui souhaitent résoudre les conflits de fusion de manière semi-manuelle:
git diff --name-status --diff-filter=U
affiche tous les fichiers qui nécessitent une résolution de conflit.
Ouvrez chacun de ces fichiers un par un ou tous en même temps en:
emacs $(git diff --name-only --diff-filter=U)
Lorsque vous visitez un tampon nécessitant des modifications dans Emacs, tapez
ALT+x vc-resolve-conflicts
Cela ouvrira trois tampons (le mien, le leur et le tampon de sortie). Naviguez en appuyant sur «n» (région suivante), «p» (région de prévision). Appuyez sur 'a' et 'b' pour copier respectivement la mienne ou la leur dans le tampon de sortie. Et / ou modifiez directement le tampon de sortie.
Une fois terminé: Appuyez sur 'q'. Emacs vous demande si vous souhaitez enregistrer ce tampon: oui. Après avoir terminé un tampon, marquez-le comme résolu en exécutant le teriminal:
git add FILENAME
Une fois terminé avec tous les types de tampons
git commit
pour terminer la fusion.
En parlant de pull / fetch / merge dans les réponses ci-dessus, je voudrais partager une astuce intéressante et productive,
git pull --rebase
Cette commande ci-dessus est la commande la plus utile de ma vie git qui a permis de gagner beaucoup de temps.
Avant de pousser votre modification nouvellement validée sur le serveur distant, essayez git pull --rebase
plutôt git pull
et manuellementmerge
et il synchronisera automatiquement les dernières modifications du serveur distant (avec une extraction + fusion) et placera votre dernière validation locale en haut dans le journal git. Pas besoin de s'inquiéter de l'extraction / fusion manuelle.
En cas de conflit, utilisez simplement
git mergetool
git add conflict_file
git rebase --continue
Plus de détails sur: http://gitolite.com/git-pull--rebase
Simplement, si vous savez bien que les changements dans l'un des référentiels ne sont pas importants et que vous souhaitez résoudre tous les changements en faveur de l'autre, utilisez:
git checkout . --ours
pour résoudre les modifications en faveur de votre référentiel , ou
git checkout . --theirs
pour résoudre les changements en faveur de l' autre ou du référentiel principal .
Sinon, vous devrez utiliser un outil de fusion GUI pour parcourir les fichiers un par un, dire que l'outil de fusion est p4merge
ou écrire le nom de quelqu'un que vous avez déjà installé
git mergetool -t p4merge
et après avoir terminé un fichier, vous devrez enregistrer et fermer, donc le suivant s'ouvrira.
Veuillez suivre les étapes suivantes pour résoudre les conflits de fusion dans Git:
Vérifiez le statut Git: statut git
Obtenez le patchset: git fetch ( récupérez le bon patch depuis votre commit Git)
Extraire une branche locale (temp1 dans mon exemple ici): git checkout -b temp1
Extraire le contenu récent de master: git pull --rebase origin master
Démarrez le mergetool et vérifiez les conflits et corrigez-les ... et vérifiez les modifications dans la branche distante avec votre branche actuelle: git mergetool
Vérifiez à nouveau l'état: git status
Supprimez les fichiers indésirables créés localement par mergetool, généralement mergetool crée un fichier supplémentaire avec l'extension * .orig. Veuillez supprimer ce fichier car il ne s'agit que du doublon et corriger les modifications localement et ajouter la version correcte de vos fichiers. git add #your_changed_correct_files
Vérifiez à nouveau l'état: git status
Validez les modifications sur le même ID de validation (cela évite un nouvel ensemble de correctifs séparé): git commit --amend
Push vers la branche master: git push (vers votre dépôt Git)
Il y a 3 étapes:
Rechercher les fichiers provoquant des conflits par commande
git status
Vérifiez les fichiers dans lesquels vous trouverez les conflits marqués comme
<<<<<<<<head
blablabla
Modifiez-le comme vous le souhaitez, puis validez avec les commandes
git add solved_conflicts_files
git commit -m 'merge msg'
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 déroulent avec les référentiels locaux et distants. La clé pour cela est de comprendre les branches de suivi. J'ai trouvé que je considère la branche de suivi comme la `` pièce manquante au milieu '' entre moi mon répertoire de fichiers local et réel et la télécommande définie comme origine.
J'ai personnellement pris l'habitude de 2 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 cela peut inclure des modifications indésirables.
b) Vous ne pouvez pas consulter la liste des fichiers en premier.
Donc à la place je fais:
git add file,file2,file3...
git commit # Then type the files in the editor and save-quit.
De cette façon, vous êtes plus délibéré sur les fichiers à ajouter et vous pouvez également consulter la liste et réfléchir un peu plus lorsque vous utilisez l'éditeur pour le message. Je trouve que cela améliore également mes messages de validation lorsque j'utilise un éditeur plein écran plutôt que l' -m
option.
[Mise à jour - au fil du temps, je suis passé à plus:
git status # Make sure I know whats going on
git add .
git commit # Then use the editor
]
Aussi (et plus pertinent pour votre situation), j'essaye d'éviter:
git pull
ou
git pull origin master.
car pull implique une fusion et si vous avez des modifications localement que vous ne vouliez pas fusionner, vous pouvez facilement vous retrouver avec du code fusionné et / ou des conflits de fusion pour du code qui n'aurait pas dû être fusionné.
Au lieu de cela, j'essaie de faire
git checkout master
git fetch
git rebase --hard origin/master # or whatever branch I want.
Vous pouvez également trouver cela utile:
git branch, fork, fetch, merge, rebase and clone, quelles sont les différences?
git checkout master
et git fetch
et git rebase --hard origin/master
git add .
oui, cela sauvera-t-il nos modifications locales afin que nous puissions poursuivre git checkout master
? ou s'agit-il de deux scénarios différents?
$ git rebase --hard origin/master b5a30cc159ba8dd error: unknown option
hard 'usage: git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>] ou: git rebase [-i] [ options] [--exec <cmd>] [--onto <newbase>] --root [<branch>] ou: git rebase --continue | --abort | --skip | --edit-todo `
La réponse de CoolAJ86 résume à peu près tout. Si vous avez des changements dans les deux branches dans le même morceau de code, vous devrez effectuer une fusion manuelle. Ouvrez le fichier en conflit dans n'importe quel éditeur de texte et vous devriez voir la structure suivante.
(Code not in Conflict)
>>>>>>>>>>>
(first alternative for conflict starts here)
Multiple code lines here
===========
(second alternative for conflict starts here)
Multiple code lines here too
<<<<<<<<<<<
(Code not in conflict here)
Choisissez l'une des alternatives ou une combinaison des deux de la manière que vous souhaitez que le nouveau code soit, tout en supprimant les signes égaux et les crochets angulaires.
git commit -a -m "commit message"
git push origin master
git log --merge -p [[--] path]
Ne semble pas toujours fonctionner pour moi et finit généralement par afficher chaque commit différent entre les deux branches, cela se produit même lors de l'utilisation --
pour séparer le chemin de la commande.
Ce que je fais pour contourner ce problème est d'ouvrir deux lignes de commande et en une seule fois
git log ..$MERGED_IN_BRANCH --pretty=full -p [path]
et dans l'autre
git log $MERGED_IN_BRANCH.. --pretty=full -p [path]
Remplacement $MERGED_IN_BRANCH
par la branche dans laquelle j'ai fusionné et [path]
par le fichier en conflit. Cette commande enregistrera toutes les validations, sous forme de patch, entre ( ..
) deux validations. Si vous laissez un côté vide comme dans les commandes ci-dessus, git utilisera automatiquement HEAD
(la branche dans laquelle vous fusionnez dans ce cas).
Cela vous permettra de voir quels commits sont entrés dans le fichier dans les deux branches après leur divergence. Cela facilite généralement la résolution des conflits.
patience
Je suis surpris que personne d'autre n'ait parlé de la résolution des conflits en utilisant patience
la stratégie récursive de fusion. Pour un gros conflit de fusion, en utilisantpatience
m'a donné de bons résultats. L'idée est qu'il essaiera de faire correspondre les blocs plutôt que les lignes individuelles.
Si vous modifiez l'indentation de votre programme par exemple, la stratégie de fusion Git par défaut correspond parfois à des accolades simples {
qui appartiennent à différentes fonctions. Ceci est évité avec patience
:
git merge -s recursive -X patience other-branch
De la documentation:
With this option, merge-recursive spends a little extra time to avoid
mismerges that sometimes occur due to unimportant matching lines
(e.g., braces from distinct functions). Use this when the branches to
be merged have diverged wildly.
Si vous avez un conflit de fusion et que vous voulez voir ce que les autres avaient en tête lors de la modification de leur branche, il est parfois plus facile de comparer directement leur branche avec l'ancêtre commun (au lieu de notre branche). Pour cela, vous pouvez utiliser merge-base
:
git diff $(git merge-base <our-branch> <their-branch>) <their-branch>
Habituellement, vous souhaitez uniquement voir les modifications pour un fichier particulier:
git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file>
Depuis le 12 décembre 2016, vous pouvez fusionner des succursales et résoudre des conflits sur github.com
Ainsi, si vous ne souhaitez pas utiliser la ligne de commande ou les outils tiers proposés ici à partir de réponses plus anciennes , utilisez l' outil natif de GitHub.
Cet article de blog explique en détail, mais les bases sont que lors de la `` fusion '' de deux branches via l'interface utilisateur, vous verrez désormais une option `` résoudre les conflits '' qui vous amènera à un éditeur vous permettant de gérer ces conflits de fusion.
Si vous souhaitez fusionner de la branche (test) au maître, vous pouvez suivre ces étapes:
Étape 1 : allez à la succursale
git checkout test
Étape 2 :
git pull --rebase origin master
Étape 3 : S'il y a des conflits, accédez à ces fichiers pour le modifier.
Étape 4 : ajoutez ces modifications
git add #your_changes_files
Étape 5 :
git rebase --continue
Étape 6 : S'il y a toujours un conflit, revenez à l'étape 3. S'il n'y a pas de conflit, procédez comme suit:
git push origin +test
Étape 7 : Et puis il n'y a pas de conflit entre le test et le maître. Vous pouvez utiliser la fusion directement.
Je respecte toujours les étapes ci-dessous pour éviter les conflits.
Maintenant, vous pouvez faire de même et maintenir autant de succursales locales que vous le souhaitez et travailler simultanément en effectuant une vérification de git dans votre succursale lorsque cela est nécessaire.
Des conflits de fusion peuvent survenir dans différentes situations:
Vous devez installer un outil de fusion compatible avec Git pour résoudre les conflits. J'utilise personnellement KDiff3, et je l'ai trouvé agréable et pratique. Vous pouvez télécharger sa version Windows ici:
https://sourceforge.net/projects/kdiff3/files/
BTW si vous installez Git Extensions, il y a une option dans son assistant de configuration pour installer Kdiff3.
Ensuite, configurez git configs pour utiliser Kdiff comme son outil de fusion:
$ git config --global --add merge.tool kdiff3
$ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add mergetool.kdiff3.trustExitCode false
$ git config --global --add diff.guitool kdiff3
$ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add difftool.kdiff3.trustExitCode false
(N'oubliez pas de remplacer le chemin par le chemin réel du fichier exe Kdiff.)
Ensuite, chaque fois que vous rencontrez un conflit de fusion, il vous suffit d'exécuter cette commande:
$git mergetool
Ensuite, il ouvre le Kdiff3 et essaie d'abord de résoudre automatiquement les conflits de fusion. La plupart des conflits seraient résolus spontanément et vous devez corriger le reste manuellement.
Voici à quoi ressemble Kdiff3:
Ensuite, une fois que vous avez terminé, enregistrez le fichier et il passe au fichier suivant avec conflit et vous recommencez jusqu'à ce que tous les conflits soient résolus.
Pour vérifier si tout a bien été fusionné, il suffit d'exécuter à nouveau la commande mergetool, vous devriez obtenir ce résultat:
$git mergetool
No files need merging
Cette réponse consiste à ajouter une alternative pour les utilisateurs de VIM comme I qui préfère tout faire dans l'éditeur.
Tpope est venu avec ce super plugin pour VIM appelé fugitif . Une fois installé, vous pouvez exécuter :Gstatus
pour vérifier les fichiers qui sont en conflit et :Gdiff
pour ouvrir Git de 3 manières.
Une fois dans la fusion à 3 voies, fugitive vous permettra d'obtenir les modifications de l'une des branches que vous fusionnez de la manière suivante:
:diffget //2
, obtenez les modifications de la branche d'origine ( HEAD )::diffget //3
, obtenez les modifications de la fusion de la branche: Une fois la fusion du fichier terminée, saisissez :Gwrite
le tampon fusionné. Vimcasts a publié une excellente vidéo expliquant en détail ces étapes.
Vous pouvez essayer Gitlense pour VS Code, leurs principales caractéristiques sont les suivantes:
J'aime déjà cette fonctionnalité:
Et il existe de nombreuses fonctionnalités que vous pouvez vérifier ici .
git fetch
git checkout votre branche
git rebase master
Dans cette étape, vous essaierez de résoudre le conflit en utilisant votre IDE préféré
Vous pouvez suivre ce lien pour vérifier comment résoudre le conflit dans le fichier
https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/
git add
git rebase --continue
git commit --amend
git push origin HEAD: refs / drafts / master (push like a drafts)
Maintenant tout va bien et vous trouverez votre commit dans gerrit
J'espère que cela aidera tout le monde concernant cette question.
Essayez Visual Studio Code pour l'édition si vous ne l'êtes pas déjà. Ce qu'il fait est après avoir essayé de fusionner (et atterrir dans des conflits de fusion). Le code VS détecte automatiquement les conflits de fusion.
Il peut vous aider très bien en montrant quelles sont les modifications apportées à l'original et si vous acceptez incoming
ou
current change
(signifiant l'original avant de fusionner) '?.
Cela m'a aidé et ça peut aussi marcher pour vous!
PS: Cela ne fonctionnera que si vous avez configuré git avec votre code et Visual Studio Code.
Un moyen plus sûr de résoudre les conflits consiste à utiliser git-mediate (les solutions courantes suggérées ici sont à mon humble avis).
Voir cet article pour une introduction rapide sur la façon de l'utiliser.
Pour ceux qui utilisent Visual Studio (2015 dans mon cas)
Fermez votre projet dans VS. Surtout dans les grands projets, VS a tendance à paniquer lors de la fusion à l'aide de l'interface utilisateur.
Faites la fusion dans l'invite de commande.
git checkout target_branch
git merge source_branch
Ouvrez ensuite le projet dans VS et accédez à Team Explorer -> Branch. Un message indique maintenant que la fusion est en attente et que les fichiers en conflit sont répertoriés juste en dessous du message.
Cliquez sur le fichier en conflit et vous aurez la possibilité de fusionner, comparer, prendre la source, prendre la cible. L'outil de fusion dans VS est très facile à utiliser.
Si vous utilisez intelliJ comme IDE Essayez de fusionner le parent avec votre branche en
git checkout <localbranch>
git merge origin/<remotebranch>
Il montrera tous les conflits comme celui-ci
A_MBPro: test anu $ git merge origin / Auto-merging src / test / java / com /.../ TestClass.java CONFLICT (content): Fusion du conflit dans src / test / java / com /.../ TestClass.java
Notez maintenant que le fichier TestClass.java est affiché en rouge dans intelliJ.
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/test/java/com/.../TestClass.java
Ouvrez le fichier dans intelliJ, il aura des sections avec
<<<<<<< HEAD
public void testMethod() {
}
=======
public void testMethod() { ...
}
>>>>>>> origin/<remotebranch>
où HEAD correspond aux modifications sur votre branche locale et à l'origine / correspond aux modifications de la branche distante. Ici, conservez les éléments dont vous avez besoin et supprimez ceux dont vous n'avez pas besoin, après quoi les étapes normales devraient suffire. C'est
git add TestClass.java
git commit -m "commit message"
git push
J'utilise le code visuel de Microsoft pour résoudre les conflits. C'est très simple à utiliser. Je garde mon projet ouvert dans l'espace de travail. Il détecte et met en évidence les conflits, donne en outre des options d'interface graphique pour sélectionner le changement que je souhaite conserver de HEAD ou entrant.