Question Comment afficher la sortie 'git diff' avec mon outil diff / viewer préféré?


Quand je tape git diff, Je veux voir la sortie avec mon outil visuel diff de choix (SourceGear "diffmerge" sur Windows). Comment est-ce que je configure git pour faire ceci?


679
2017-10-31 22:55


origine


Réponses:


Depuis Git1.6.3, vous pouvez utiliser le git script difftool: voir ma réponse ci-dessous.


Peut être ça article va vous aider. Voici les meilleures parties:

Il existe deux manières différentes de spécifier un outil de comparaison externe.

La première est la méthode que vous avez utilisée, en définissant la variable GIT_EXTERNAL_DIFF. Cependant, la variable est censée pointer vers le chemin complet de l'exécutable. De plus, l'exécutable spécifié par GIT_EXTERNAL_DIFF sera appelé avec un ensemble fixe de 7 arguments:

path old-file old-hex old-mode new-file new-hex new-mode

Comme la plupart des outils diff nécessitent un ordre différent (et seulement quelques uns) des arguments, vous devrez probablement spécifier un script wrapper, qui à son tour appelle l'outil de comparaison réel.

La deuxième méthode, que je préfère, est de configurer l'outil de comparaison externe via "git config ". Voici ce que j'ai fait:

1) Créez un script wrapper "git-diff-wrapper.sh" qui contient quelque chose comme

-->8-(snip)--
#!/bin/sh

# diff is called by git with 7 parameters:
# path old-file old-hex old-mode new-file new-hex new-mode

"<path_to_diff_executable>" "$2" "$5" | cat
--8<-(snap)--

Comme vous pouvez le voir, seuls les deuxième ("old-file") et cinquième ("new-file") arguments seront passé à l'outil de diff.

2) Type

$ git config --global diff.external <path_to_wrapper_script>

à l'invite de commande, en remplaçant par le chemin d'accès à "git-diff-wrapper.sh", ainsi votre ~ / .gitconfig contient

-->8-(snip)--
[diff]
    external = <path_to_wrapper_script>
--8<-(snap)--

Veillez à utiliser la syntaxe correcte pour spécifier les chemins d'accès au script wrapper et diff l'outil, c'est-à-dire l'utilisation de la barre oblique au lieu de barres obliques inverses. Dans mon cas, j'ai

[diff]
    external = \"c:/Documents and Settings/sschuber/git-diff-wrapper.sh\"

dans .gitconfig et

"d:/Program Files/Beyond Compare 3/BCompare.exe" "$2" "$5" | cat

dans le script d'encapsulation. Attention au "chat" qui traîne!

(Je suppose que le '| cat'n'est nécessaire que pour certains programmes qui peuvent ne pas renvoyer un état de retour correct ou cohérent. Vous pourriez vouloir essayer sans le chat de fuite si votre outil de diff a un statut de retour explicite)


Cela (l'article cité ci-dessus) est la théorie de l'outil externe défini par le fichier de configuration (pas à travers la variable d'environnement).
En pratique (toujours pour la définition du fichier de configuration de l'outil externe), vous pouvez vous référer à:


366
2017-10-31 23:03



Pour compléter mon précédent Réponse de configuration "diff.external" au dessus:

Comme mentionné par Jakub, Git1.6.3 introduit git difftool, initialement proposé en septembre 2008:

USAGE ='[--tool=tool] [--commit=ref] [--start=ref --end=ref] [--no-prompt] [file to merge]'
(Voir --extcmd dans la dernière partie de cette réponse)

$LOCAL contient le contenu du fichier de la révision de départ et $REMOTE contient le contenu du fichier dans la révision de fin.
$BASE contient le contenu du fichier dans le wor

C'est essentiellement git-mergetool modifié pour fonctionner sur l'index git / worktree.

Le scénario d'utilisation habituel pour ce script est lorsque vous avez des modifications staging ou non statiques et que vous souhaitez voir les modifications dans un visualisateur diff côte à côte (par ex. xxdiff, tkdiff, etc).

git difftool [<filename>*]

Un autre cas d'utilisation est quand vous voulez voir la même information mais comparez des commits arbitraires (c'est la partie où l'analyse de revarg pourrait être meilleure)

git difftool --start=HEAD^ --end=HEAD [-- <filename>*]

Le dernier cas d'utilisation est lorsque vous souhaitez comparer votre arborescence de travail actuelle à autre chose que HEAD (par exemple, une balise)

git difftool --commit=v1.0.0 [-- <filename>*]

Note: depuis Git 2.5, git config diff.tool winmerge est assez!
Voir "git mergetool winmerge"

Et depuis Git 1.7.11, vous avez l'option --dir-diff, afin de générer des outils de comparaison externes qui peuvent comparer deux hiérarchies de répertoires à la fois après le remplissage de deux répertoires temporaires, au lieu d'exécuter une instance de l'outil externe une fois par paire de fichiers.


Avant Git 2.5:

Cas pratique pour la configuration difftool avec votre outil de comparaison personnalisé:

C:\myGitRepo>git config --global diff.tool winmerge
C:\myGitRepo>git config --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\""
C:\myGitRepo>git config --global difftool.prompt false

Avec winmerge.sh stocké dans une partie du répertoire de votre PATH:

#!/bin/sh
echo Launching WinMergeU.exe: $1 $2
"C:/Program Files/WinMerge/WinMergeU.exe" -u -e "$1" "$2" -dl "Local" -dr "Remote"

Si vous avez un autre outil (kdiff3, P4Diff, ...), créez un autre script shell, et le difftool.myDiffTool.cmd directive config.
Ensuite, vous pouvez facilement changer d'outils avec le diff.tool config.

Vous avez aussi ceci entrée de blog par Dave ajouter d'autres détails
(Ou cette question pour le winmergeu options)

L'intérêt avec ce paramètre est le winmerge.shscénario: vous pouvez le personnaliser pour prendre en compte des cas particuliers.

Voir par exemple David Marblede Réponse ci-dessous pour un exemple qui concerne:

  • Nouveau fichiers dans l'origine ou la destination
  • supprimé fichiers dans l'origine ou la destination

Comme Kem Mason mentions dans sa réponse, vous pouvez aussi éviter tout emballage en utilisant le --extcmd option:

--extcmd=<command>

Spécifiez une commande personnalisée pour afficher les différences. git-difftool ignore les valeurs par défaut configurées et s'exécute $command $LOCAL $REMOTE lorsque cette option est spécifiée.

Par exemple, voici comment gitk est capable de courir / utiliser n'importe diff outil.


195
2018-06-04 08:25



Dans l'esprit de répondre à des questions qui sont quelque peu différentes de celles posées. Essayez cette solution:

$ meld my_project_using_git

Meld comprend git et permet de naviguer autour des changements récents.


105
2018-03-14 16:28



Depuis la version 1.6.3 de git il y a "git difftool"que vous pouvez configurer pour utiliser votre outil de comparaison graphique préféré. kdiff3, kompare, tkdiff, fusion, xxdiff, émergent, vimdiff, gvimdiff, ecmerge, diffuse et opendiff; Si l'outil que vous souhaitez utiliser ne figure pas dans cette liste, vous pouvez toujours utiliser 'difftool.<tool>.cmd'option de configuration.

"git difftool" accepte les mêmes options que "git diff".


38
2018-05-23 11:37



Avec nouveau git difftool, c'est aussi simple que d'ajouter ceci à votre .gitconfig fichier:

[diff]
    tool = any-name
[difftool "any-name"]
    cmd = "\"C:/path/to/my/ext/diff.exe\" \"$LOCAL\" \"$REMOTE\""

Consultez également diffall, un script simple que j'ai écrit pour prolonger le comportement diff diffcile ennuyeux (IMO) de chaque ouverture en série.


34
2017-08-27 09:39



J'ai un ajout à cela. J'aime utiliser régulièrement une application diff qui n'est pas supportée comme l'un des outils par défaut (par exemple kaléidoscope), via

git difftool -t

J'aime aussi avoir la valeur par défaut diff juste être la ligne de commande régulière, afin de définir la GIT_EXTERNAL_DIFF variable n'est pas une option.

Vous pouvez utiliser un arbitraire diff application en tant que one-off avec cette commande:

git difftool --extcmd=/usr/bin/ksdiff

Il passe simplement les 2 fichiers à la commande que vous spécifiez, donc vous n'avez probablement pas non plus besoin d'un wrapper.


21
2018-02-03 00:16



S'appuyant sur la réponse de VonC pour gérer les suppressions et les ajouts de fichiers, utilisez les commandes et scripts suivants:

> git config --global diff.tool winmerge
> git config --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\" \"$BASE\""
> git config --global difftool.prompt false

Ce qui est la même chose que de mettre cela dans votre global .gitconfig:

[diff]
    tool = winmerge
[difftool "winmerge"]
    cmd = winmerge.bat "$LOCAL" "$REMOTE" "$BASE"
[difftool]
    prompt = false

Ensuite, mettez ce qui suit dans winmerge.shqui doit être sur ton chemin:

#!/bin/sh
NULL="/dev/null"
if [ "$2" = "$NULL" ] ; then
    echo "removed: $3"
elif [ "$1" = "$NULL" ] ; then
    echo "added: $3"
else
    echo "changed: $3"
    "C:/Program Files (x86)/WinMerge/WinMergeU.exe" -e -ub -dl "Base" -dr "Mine" "$1" "$2"
fi

17
2017-11-07 07:12