Je viens de fusionner une branche dans mon maître dans git et j'ai eu Automatic merge failed; fix conflicts and then commit the result.
Maintenant j'ai couru git mergetool
et vimdiff s'ouvrent avec l'image ci-dessous. Je ne sais pas comment utiliser vimdiff. Que signifie chaque panneau ici et comment dois-je procéder pour résoudre le conflit de fusion?
Les quatre mémoires tampons fournissent une vue différente du même fichier. Le tampon en haut à gauche (LOCAL) correspond à l'apparence du fichier dans votre branche cible (en quoi vous fusionnez). Le tampon en haut à droite (REMOTE) correspond à l'apparence du fichier dans votre branche source (à partir de laquelle vous effectuez la fusion). Le tampon central (BASE) est l’ancêtre commun des deux (vous pouvez donc comparer les différences entre les versions gauche et droite).
Je peux me tromper sur le point suivant. Je pense que la source du conflit de fusion est que les deux fichiers ont changé la même partie du fichier depuis BASE; LOCAL a changé les guillemets de doubles en simples, et REMOTE a fait le même changement mais a également changé la valeur d'arrière-plan d'une couleur à une URL. (Je pense que la fusion n'est pas assez intelligente pour remarquer que tous les changements apportés à LOCAL sont également présents dans REMOTE; il sait simplement que LOCAL a effectué des changements depuis BASE aux mêmes endroits que REMOTE).
Dans tous les cas, le tampon inférieur contient le fichier que vous pouvez réellement éditer, celui qui se trouve dans votre répertoire de travail. Vous pouvez apporter les modifications souhaitées. vim
vous montre en quoi elle diffère de chacune des vues de dessus, qui sont les zones que la fusion automatique ne pouvait pas gérer. Tirez les changements de LOCAL si vous ne voulez pas les changements à distance. Tirez les changements de REMOTE si vous préférez ceux-ci aux changements LOCAUX. Tirez de BASE si vous pensez que REMOTE et LOCAL sont incorrects. Faites quelque chose de complètement différent si vous avez une meilleure idée! En fin de compte, les modifications que vous apportez ici sont celles qui seront réellement engagées.
La réponse de @ chepner est excellente, je voudrais ajouter quelques détails sur la partie "de la procédure à suivre pour résoudre le conflit de fusion". Si vous regardez comment utiliser réellement vimdiff dans ce cas, cela ira plus bas.
Tout d’abord, adressez-vous à l’option "Tout annuler" - si vous ne souhaitez pas utiliser "vimdiff" et que vous souhaitez annuler la fusion: appuyez sur Esc, puis tapez :qa!
et frapper Enter. (voir aussi Comment puis-je quitter l'éditeur Vim? ). Git vous demandera si la fusion est complète, répondez avec n
.
Si vous souhaitez utiliser vimdiff, voici quelques raccourcis utiles. Cela suppose que vous connaissez les bases de Vim (navigation et mode insertion/normal):
:diffget LO
:diffget RE
:diffget BA
:wqa
:cquit
à la place: Comment annuler un diff git externe?Il ne semble pas possible d'ajouter des éléments de conflit locaux et distants sans copier-coller ni raccourcis personnalisés: https://vi.stackexchange.com/questions/10534/is-there-a-way-to- take-both-when-using-vim-as-merge-tool , ce qui est dommage, car add add est un type de conflit courant.
Pour empêcher vimdiff de vous demander d’appuyer sur Entrée à chaque démarrage, ajoutez à votre .vimrc
:
set shortmess=Ot
comme mentionné à: https://vi.stackexchange.com/questions/771/how-can-i-suppress-the-press-enter-Prompt-when-opening-files-in-diff-mode
Vous pouvez rechercher sur Internet d'autres raccourcis vimdiff. J'ai trouvé celui-ci utile: https://Gist.github.com/hyamamoto/7783966
Comment différencier entre (BASE et LOCAL) et (BASE et REMOTE) avec vim -d
Lors de la résolution des conflits de fusion, l'une des choses les plus importantes à voir est la suivante:
pour ensuite essayer de les mettre ensemble.
Bien que vimdiff
fasse un bon travail en montrant côte à côte tous les types BASE, LOCAL et REMOTE, je ne peux pas clairement voir les deux diffs distincts de BASE:
+--------------------------------+
| LOCAL | BASE | REMOTE |
+--------------------------------+
| MERGED |
+--------------------------------+
Pour résoudre ce problème, j’ai remarqué que, alors que git mergetool
exécute vimdiff
, s'il existe un conflit sur un fichier nommé, disons main.py
, git génère des fichiers pour chacune des versions, nommés ainsi:
main_BASE_1367.py
main_LOCAL_1367.py
main_REMOTE_1367.py
dans le même répertoire que main.py
où 1367
est le PID de git mergetool, et donc un entier "aléatoire", comme indiqué à: Dans un conflit de fusion de git, quels sont les fichiers BACKUP, BASE, LOCAL et REMOTE générés?
Donc, pour voir les diffs que je veux, je commence par trouver les fichiers générés avec git status
, puis ouvrez de nouveaux terminaux et faites un vimdiff entre les paires de fichiers qui me tiennent à cœur:
vim -d main_BASE_1367.py main_LOCAL_1367.py
vim -d main_BASE_1367.py main_REMOTE_1367.py
Ensemble avec git mergetool
, cette information aide beaucoup à comprendre rapidement ce qui se passe!
De plus, même si mergetool est en cours d'exécution, vous pouvez simplement ouvrir le fichier:
vim main.py
directement et éditez-le ici si vous pensez que ce sera plus facile avec une plus grande fenêtre d’éditeur.
Je suppose que nous pourrions automatiser encore davantage pour ouvrir automatiquement tous ces fichiers, mais je ne me suis pas encore aventuré là-bas.
Aller directement à la fusion des conflits
Tandis que ]c
saute au prochain point de diff dans vimdiff, il n’ya pas toujours de conflit de fusion.
Pour aider avec ceci, j'ai dans mon ~/.vimrc
:
# Git Merge conflict
nnoremap <leader>gm /\v^\<\<\<\<\<\<\< \|\=\=\=\=\=\=\=$\|\>\>\>\>\>\>\> /<cr>
qui trouve les conflits directement.