Configurer et utiliser Meld en tant que git difftool et mergetool

256

Bien que la plupart des informations contenues dans cette question et réponse soient disponibles sur StackOverflow , elles sont réparties sur de nombreuses pages et parmi d'autres réponses qui sont soit fausses, soit trompeuses. Il m'a fallu un certain temps pour rassembler tout ce que je voulais savoir.

Il existe de nombreux programmes différents qui peuvent être utilisés comme git difftool et mergetool, et il n'y a certainement pas de consensus sur le meilleur (les opinions, les exigences et les systèmes d'exploitation différeront clairement).

Meld est un choix populaire gratuit, open source et multiplateforme (UNIX / Linux, OSX, Windows) comme indiqué dans la question StackOverflow , Quel est le meilleur outil de fusion visuelle pour Git? , dans lequel la réponse proposant Meld a plus de 3 fois plus de voix que tout autre outil.

Les 2 questions suivantes recevront une réponse dans ma réponse ci-dessous:

  • Comment configurer et utiliser Meld comme outil de diff git?
  • Comment configurer et utiliser Meld comme mon outil de fusion git?

Remarque: Il n'est pas nécessaire d'utiliser le même programme que votre outil difftool et mergetool, différents programmes peuvent être définis pour les deux.

mattst
la source
1
Article connexe - Comment configurer un outil diff dans Git en général .
RBT

Réponses:

423

Comment configurer et utiliser Meld comme outil de diff git?

git difftool affiche le diff à l'aide d'un programme diff GUI (c'est-à-dire Meld) au lieu d'afficher la sortie diff dans votre terminal.

Bien que vous puissiez définir le programme GUI sur la ligne de commande à l'aide, -t <tool> / --tool=<tool>il est plus logique de le configurer dans votre .gitconfigfichier. [Remarque: voir les sections sur les citations d'échappement et les chemins Windows en bas.]

# Add the following to your .gitconfig file.
[diff]
    tool = meld
[difftool]
    prompt = false
[difftool "meld"]
    cmd = meld "$LOCAL" "$REMOTE"

[Remarque: Ces paramètres ne modifieront pas le comportement git diffqui continuera de fonctionner comme d'habitude.]

Vous utilisez git difftoolexactement de la même manière que vous utilisez git diff. par exemple

git difftool <COMMIT_HASH> file_name
git difftool <BRANCH_NAME> file_name
git difftool <COMMIT_HASH_1> <COMMIT_HASH_2> file_name

Si elle est correctement configurée, une fenêtre de fusion s'ouvrira affichant le diff à l'aide d'une interface graphique.

L'ordre des vitres de fenêtre GUI Meld peut être commandé par l'ordre de $LOCALet $REMOTEdans cmd, à savoir le fichier qui est représenté dans le volet gauche et qui , dans le panneau de droite. Si vous les voulez dans l'autre sens, échangez-les simplement comme ceci:

    cmd = meld "$REMOTE" "$LOCAL"

Enfin, la prompt = falseligne empêche simplement git de vous demander si vous souhaitez lancer Meld ou non, par défaut, git émettra une invite.


Comment configurer et utiliser Meld comme mon outil de fusion git?

git mergetool vous permet d'utiliser un programme de fusion GUI (c'est-à-dire Meld) pour résoudre les conflits de fusion qui se sont produits pendant une fusion.

Comme difftool, vous pouvez définir le programme GUI sur la ligne de commande en utilisant -t <tool> / --tool=<tool>mais, comme précédemment, il est plus logique de le configurer dans votre .gitconfigfichier. [Remarque: voir les sections sur les citations d'échappement et les chemins Windows en bas.]

# Add the following to your .gitconfig file.
[merge]
    tool = meld
[mergetool "meld"]
    # Choose one of these 2 lines (not both!) explained below.
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"
    cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"

Vous n'utilisez PAS git mergetoolpour effectuer une fusion réelle. Avant d'utiliser, git mergetoolvous effectuez une fusion de la manière habituelle avec git. par exemple

git checkout master
git merge branch_name

S'il y a un conflit de fusion, git affichera quelque chose comme ceci:

$ git merge branch_name
Auto-merging file_name
CONFLICT (content): Merge conflict in file_name
Automatic merge failed; fix conflicts and then commit the result.

À ce stade file_name, contiendra le fichier partiellement fusionné avec les informations de conflit de fusion (c'est le fichier avec toutes les entrées >>>>>>>et <<<<<<<en lui).

Mergetool peut désormais être utilisé pour résoudre les conflits de fusion. Vous démarrez très facilement avec:

git mergetool

Si elle est correctement configurée, une fenêtre de fusion s'ouvrira affichant 3 fichiers. Chaque fichier sera contenu dans un volet séparé de son interface graphique.

Dans l'exemple .gitconfigci-dessus, 2 lignes sont suggérées comme [mergetool "meld"] cmdligne. En fait, il existe toutes sortes de façons pour les utilisateurs avancés de configurer la cmdligne, mais cela dépasse le cadre de cette réponse.

Cette réponse a 2 cmdlignes alternatives qui, entre elles, répondront à la plupart des utilisateurs et seront un bon point de départ pour les utilisateurs avancés qui souhaitent faire passer l'outil au niveau de complexité suivant.

Voici d'abord ce que signifient les paramètres:

  • $LOCAL est le fichier dans la branche courante (par exemple maître).
  • $REMOTE est le fichier dans la branche en cours de fusion (par exemple nom_branche).
  • $MERGED est le fichier partiellement fusionné contenant les informations de conflit de fusion.
  • $BASEest l'ancêtre de commit partagé $LOCALet $REMOTE, c'est-à-dire le fichier tel qu'il était lorsque la branche contenant $REMOTEa été créée à l'origine.

Je vous suggère d'utiliser soit:

[mergetool "meld"]
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"

ou:

[mergetool "meld"]
    cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"
    # See 'Note On Output File' which explains --output "$MERGED".

Le choix est d'utiliser $MERGEDou $BASEentre $LOCALet entre $REMOTE.

Dans tous les cas, Meld affichera 3 volets avec $LOCALet $REMOTEdans les volets gauche et droit et soit $MERGEDou $BASEdans le volet central.

Dans les DEUX cas, le volet central est le fichier que vous devez modifier pour résoudre les conflits de fusion. La différence est juste la position de montage que vous préférez; $MERGEDpour le fichier qui contient le fichier partiellement fusionné avec les informations de conflit de fusion ou $BASEpour l'ancêtre de validation partagée de $LOCALet $REMOTE. [Puisque les deux cmdlignes peuvent être utiles, je les garde toutes les deux dans mon .gitconfigdossier. La plupart du temps, j'utilise la $MERGEDligne et la $BASEligne est mise en commentaire, mais la mise en commentaire peut être permutée si je veux utiliser la $BASEligne à la place.]

Remarque sur le fichier de sortie: ne vous inquiétez pas de ce qui --output "$MERGED"est utilisé dans, cmdqu'il ait été utilisé $MERGEDou non $BASEplus tôt dans la cmdligne. L' --outputoption indique simplement à Meld dans quel nom de fichier git souhaite que le fichier de résolution des conflits soit enregistré. Meld enregistrera vos modifications de conflit dans ce fichier, que vous l'utilisiez $MERGEDou $BASEcomme point de départ.

Après avoir modifié le volet central pour résoudre les conflits de fusion, enregistrez simplement le fichier et fermez la fenêtre Fusionner. Git effectuera la mise à jour automatiquement et le fichier dans la branche actuelle (par exemple master) contiendra désormais tout ce que vous avez fini dans le volet central.

git aura effectué une sauvegarde du fichier partiellement fusionné avec les informations de conflit de fusion en y ajoutant .origle nom de fichier d'origine. par exemple file_name.orig. Après avoir vérifié que la fusion vous .origconvient et exécuté les tests que vous souhaitez effectuer, le fichier peut être supprimé.

À ce stade, vous pouvez maintenant faire un commit pour valider les modifications.

Si, pendant que vous modifiez les conflits de fusion dans Meld, vous souhaitez abandonner l'utilisation de Meld, puis quittez Meld sans enregistrer le fichier de résolution de fusion dans le volet central. git répondra avec le message file_name seems unchangedet demandera ensuite Was the merge successful? [y/n], si vous répondez nalors la résolution du conflit de fusion sera abandonnée et le fichier restera inchangé. Notez que si vous avez enregistré le fichier dans Meld à tout moment, vous ne recevrez pas l'avertissement et l'invite de git. [Bien sûr, vous pouvez simplement supprimer le fichier et le remplacer par le .origfichier de sauvegarde que git a fait pour vous.]

Si vous avez plus d'un fichier avec des conflits de fusion, git ouvrira une nouvelle fenêtre de fusion pour chacun, l'un après l'autre jusqu'à ce qu'ils soient tous terminés. Ils ne seront pas tous ouverts en même temps, mais lorsque vous aurez terminé de modifier les conflits en un seul et que vous fermerez Meld, git ouvrira le suivant, et ainsi de suite jusqu'à ce que tous les conflits de fusion soient résolus.

Il serait judicieux de créer un projet factice pour tester l'utilisation de git mergetoolavant de l'utiliser sur un projet en direct . Assurez-vous d'utiliser un nom de fichier contenant un espace dans votre test, au cas où votre système d'exploitation vous obligerait à échapper les guillemets dans la cmdligne, voir ci-dessous.


Échapper les caractères de citation

Certains systèmes d'exploitation peuvent nécessiter que les guillemets soient cmdéchappés. Les utilisateurs moins expérimentés doivent se rappeler que les lignes de commande de configuration doivent être testées avec des noms de fichiers qui incluent des espaces, et si les cmdlignes ne fonctionnent pas avec les noms de fichiers qui incluent des espaces, essayez d'échapper les guillemets. par exemple

cmd = meld \"$LOCAL\" \"$REMOTE\"

Dans certains cas, un échappement de citation plus complexe peut être nécessaire. Le premier des liens de chemin Windows ci-dessous contient un exemple de triple échappement de chaque citation. C'est ennuyeux mais parfois nécessaire. par exemple

cmd = meld \\\"$LOCAL\\\" \\\"$REMOTE\\\"

Chemins Windows

Les utilisateurs de Windows auront probablement besoin d'une configuration supplémentaire ajoutée aux cmdlignes de fusion . Ils peuvent avoir besoin d'utiliser le chemin d'accès complet à meldc, qui est conçu pour être appelé sous Windows à partir de la ligne de commande, ou ils peuvent avoir besoin ou vouloir utiliser un wrapper. Ils devraient lire les pages StackOverflow liées ci-dessous qui concernent la définition de la cmdligne de fusion correcte pour Windows. Étant donné que je suis un utilisateur Linux, je ne peux pas tester les différentes cmdlignes de Windows et je n'ai pas d'autres informations sur le sujet que de recommander d'utiliser mes exemples avec l'ajout d'un chemin complet vers Meld ou meldc, ou l'ajout du dossier du programme Meld à votre path.

Ignorer les espaces de fin avec Meld

Meld a un certain nombre de préférences qui peuvent être configurées dans l'interface graphique.

Dans l' Text Filtersonglet Préférences, il existe plusieurs filtres utiles pour ignorer des éléments tels que les commentaires lors de l'exécution d'un diff. Bien qu'il y ait des filtres à ignorer All whitespaceet Leading whitespace, il n'y a pas de Trailing whitespacefiltre d' ignorance (cela a été suggéré comme ajout dans la liste de diffusion Meld mais n'est pas disponible dans ma version).

Ignorer les espaces de fin est souvent très utile, en particulier lors de la collaboration, et peut être ajouté manuellement facilement avec une simple expression régulière dans l' Text Filtersonglet Préférences de fusion .

# Use either of these regexes depending on how comprehensive you want it to be.
[ \t]*$
[ \t\r\f\v]*$

J'espère que cela aide tout le monde.

mattst
la source
2
Merci, c'est beaucoup plus facile à utiliser [mergetool "meld"] cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"dans ~/.gitconfig, puis juste résoudre les conflits en rouge dans la casserole moyenne et économisez! Ce devrait être le paramètre par défaut.
KrisWebDev
1
$LOCAL $MERGED $REMOTEest le paramètre que j'utilise la plupart du temps, lorsqu'il n'y a que quelques conflits pour résoudre, c'est excellent et c'est aussi ma valeur par défaut. $LOCAL $BASE $REMOTEprend tout son sens lorsqu'il y a beaucoup à faire et que vous savez exactement quelles sections de code proviennent de quel fichier; l'ancêtre de commit partagé peut être un excellent point de départ sans encombrement, parfois la mise en évidence du conflit se met en travers du chemin et une base plus propre est une bénédiction.
mattst
4
Remarque: Si vous êtes sur OSX et que vous avez installé le meld via homebrew, le paramètre de sortie nécessitera un =comme ceci:cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output="$MERGED"
Alteisen
2
Pour les utilisateurs de Mac qui ont installé le .dmg et trouvent que 'meld' n'est pas sur leur chemin, assurez-vous de suivre les instructions alternatives ici: yousseb.github.io/meld
KC Baltz
3
C'est tellement mieux que l'explication de Git Configuration - git mergetool . Merci beaucoup surtout d'avoir expliqué la différence entre $ MERGED et $ BASE. M'a sauvé de devenir fou!
ChrisG
81

Alors que l'autre réponse est correcte, voici le moyen le plus rapide de continuer et de configurer Meld en tant qu'outil de comparaison visuelle. Copiez / collez simplement ceci:

git config --global diff.tool meld
git config --global difftool.prompt false

Maintenant exécuté git difftooldans un répertoire et Meld sera lancé pour chaque fichier différent.

Note latérale: Meld est étonnamment lent à comparer les fichiers CSV, et aucun outil de diff Linux que j'ai trouvé n'est plus rapide que cet outil Windows appelé Compare It! (dernière mise à jour en 2010).

Dan Dascalescu
la source
13
Vous voulez probablement aussi une git config --global difftool.meld.cmd 'meld "$LOCAL" "$REMOTE"'ligne là-dedans. Il s'agit de la "valeur par défaut", mais dès que vous configurez un mergetool, le difftoolcommencera à utiliser la configuration de mergetool comme valeur par défaut si la configuration diff n'est pas trouvée. Étant donné que la fusion est généralement configurée pour passer trois fichiers pour une fusion à 3 voies, cela signifie que votre fenêtre de meld diff aura soudainement trois volets, ce qui n'a aucun sens.
BeeOnRope
Pourquoi ne pas vérifier la configuration, après avoir défini avec $ git config -l
agfe2
56

Pour Windows . Exécutez ces commandes dans Git Bash:

git config --global diff.tool meld
git config --global difftool.meld.path "C:\Program Files (x86)\Meld\Meld.exe"
git config --global difftool.prompt false

git config --global merge.tool meld
git config --global mergetool.meld.path "C:\Program Files (x86)\Meld\Meld.exe"
git config --global mergetool.prompt false

(Mettez à jour le chemin d'accès au fichier pour Meld.exe si le vôtre est différent.)

Pour Linux . Exécutez ces commandes dans Git Bash:

git config --global diff.tool meld
git config --global difftool.meld.path "/usr/bin/meld"
git config --global difftool.prompt false

git config --global merge.tool meld
git config --global mergetool.meld.path "/usr/bin/meld"
git config --global mergetool.prompt false

Vous pouvez vérifier le chemin de Meld en utilisant cette commande:

which meld
MarredCheese
la source
1
J'ai reçu une erreur lorsque j'exécute git difftool "Le meld d'outil diff n'est pas disponible en tant que 'D: \ software \ melddiff \ Meld.exe'"
Allen Vork
@AllenVork: Avez-vous confirmé que Meld.exe se trouve dans le dossier que vous avez spécifié? Pouvez-vous l'exécuter en dehors de Git avec succès? Que retourne Git lorsque vous courez git config --global --get-regex diff*?
MarredCheese
Je l'ai résolu. Je le change en "D: /software/melddiff/Meld.exe" et cela fonctionne. Le format de .gitconfig est ubuntu pas Windows.
Allen Vork
Cela n'aurait-il pas dû être git config --global difftool.meld.path "C:\Program Files (x86)\Meld\Meld.exe":?
Jonathan Rosenne
@AllenVork, utilisez-vous git pour cygwin?
Adrian
25

Je préfère configurer meld en tant que commande distincte, comme ceci:

git config --global alias.meld '!git difftool -t meld --dir-diff'

Cela le rend similaire au script git-meld.pl ici: https://github.com/wmanley/git-meld

Vous pouvez alors simplement exécuter

git meld
Ulf Adams
la source
Je venais de travailler avec Cygwin et maintenant c'est cassé. Cela l'a corrigé. Merci! (Bien que j'aie supprimé la --dir-diffpartie comme préférence personnelle.)
PfunnyGuy
3

Pour Windows 10, je devais mettre cela dans mon .gitconfig:

[merge]
  tool = meld
[mergetool "meld"]
  cmd = 'C:/Program Files (x86)/Meld/Meld.exe' $LOCAL $BASE $REMOTE --output=$MERGED
[mergetool]
  prompt = false

Tout ce que vous devez savoir est écrit dans cette super réponse de mattst plus haut.

PS: Pour une raison quelconque, cela ne fonctionnait qu'avec Meld 3.18.x, Meld 3.20.x me donne une erreur.

Jeremy Benks
la source
1

Il s'agit d'une réponse ciblant principalement les développeurs utilisant Windows, car la syntaxe du chemin d'accès de l'outil diff diffère des autres plates-formes.

J'utilise Kdiff3 comme gerg mergetool, mais pour configurer git difftool en tant que Meld, j'ai d'abord installé la dernière version de Meld de Meldmerge.org, puis ajouté ce qui suit à mon .gitconfig global en utilisant:

git config --global -e

Remarque, si vous souhaitez plutôt Sublime Text 3 au lieu du Vim par défaut comme core ditor, vous pouvez l'ajouter au fichier .gitconfig:

[core]
editor = 'c:/Program Files/Sublime Text 3/sublime_text.exe'

Ensuite, vous ajoutez Inn Meld comme l'outil de difftool

[diff]
tool = meld
guitool = meld 

[difftool "meld"]
cmd = \"C:/Program Files (x86)/Meld/Meld.exe\" \"$LOCAL\" \"$REMOTE\" --label \"DIFF 
(ORIGINAL MY)\"
prompt = false
path = C:\\Program Files (x86)\\Meld\\Meld.exe

Notez la barre oblique dans le cmd ci-dessus, sous Windows, il est nécessaire.

Il est également possible de configurer un alias pour afficher le diff git actuel avec un --dir-diff option . Cela répertoriera les fichiers modifiés dans Meld, ce qui est pratique lorsque vous avez modifié plusieurs fichiers (un scénario très courant en effet).

L'alias ressemble à ceci dans le fichier .gitconfig, sous la section [alias] :

showchanges = difftool --dir-diff

Pour afficher les modifications que j'ai apportées au code, je saisis simplement la commande suivante:

git showchanges

L'image suivante montre comment cette option --dir-diff peut afficher une liste des fichiers modifiés (exemple): Fusion montrant la liste des fichiers avec des changements entre $ LOCAL et $ REMOTE

Ensuite, il est possible de cliquer sur chaque fichier et d'afficher les modifications à l'intérieur de Meld.

Tore Aurstad
la source
0

Il peut être compliqué de calculer un diff dans votre tête à partir des différentes sections de $ MERGED et de l'appliquer. Dans ma configuration, meld aide en vous montrant ces différences visuellement, en utilisant:

[merge]
    tool = mymeld
    conflictstyle = diff3

[mergetool "mymeld"]
    cmd = meld --diff $BASE $REMOTE --diff $REMOTE $LOCAL --diff $LOCAL $MERGED

Cela semble étrange mais offre un flux de travail très pratique, utilisant trois onglets:

  1. dans l'onglet 1, vous voyez (de gauche à droite) la modification que vous devez apporter dans l'onglet 2 pour résoudre le conflit de fusion.

  2. dans le côté droit de l'onglet 2, vous appliquez la «modification que vous devez apporter» et copiez le contenu complet du fichier dans le presse-papiers (en utilisant ctrl-a et ctrl-c).

  3. dans l'onglet 3, remplacez le côté droit par le contenu du presse-papiers. Si tout est correct, vous verrez maintenant - de gauche à droite - le même changement que celui indiqué dans l'onglet 1 (mais avec des contextes différents). Enregistrez les modifications apportées dans cet onglet.

Remarques:

  • ne modifiez rien dans l'onglet 1
  • ne sauvegardez rien dans l'onglet 2 car cela produira des popups ennuyeux dans l'onglet 3
mnieber
la source
Est-ce mieux que la fusion à 3 voies (local / base / distant) dans un seul onglet?
André Werlang
@ AndréWerlang L'avantage de la fusion à trois dans un seul onglet est que vous n'avez besoin de gérer que les modifications conflictuelles (les autres modifications sont fusionnées automatiquement). Mais je préfère «ma» approche dans les cas où il est difficile de comprendre dans la fusion à 3 voies ce qui a changé, et comment fusionner d'une manière qui préserve toutes les modifications. Si à un moment donné la fusion à 3 ne me dérange plus, je peux y revenir.
mnieber
Comme l'a souligné l'utilisateur mattst, vous pouvez utiliser $BASEau lieu de $MERGEDpour commencer l'opération de fusion
André Werlang