120 votes

utiliser Winmerge à l'intérieur de Git pour différencier les fichiers

Existe-t-il un moyen d'utiliser Winmerge à l'intérieur de git pour faire des Diffs ?

0 votes

0 votes

Article connexe - Comment faire configurer un outil de diff dans Git en général .

131voto

VonC Points 414372

Mise à jour de juin 2015, 6 ans plus tard :

Comme détaillé dans " git mergetool winmerge ", un simple git config diff.tool winmerge sera suffisant.

Git 2.5+ (Q2, 2015) est maintenant conscient de Winmerge comme outil de diff ou de fusion !


Réponse originale (2009-2012)

(msysgit, 1.6.5, session DOS)

La première partie (utilisation de winmerge) est décrite dans " Comment visualiser la sortie de 'git diff' avec le programme visual diff ? "

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

Avec winmerge.sh stocké dans un répertoire faisant partie de votre PATH :

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

(voir Options de la ligne de commande de WinMerge )

git difftool

va maintenant lancer WinMerge.
Si vous voulez git diff pour lancer WinMerge, il suffit de le définir :

set GIT_EXTERNAL_DIFF=winmerge.sh

Mais la véritable valeur ajoutée vient de la possibilité d'utiliser ce même outil de comparaison pour présenter toutes les différences en un seul lot au lieu de les présenter séquentiellement, ce qui vous oblige à fermer les fenêtres de l'outil de comparaison un fichier à la fois.

Mise à jour juin 2012 (2 ans et demi plus tard) :

La comparaison de répertoires au lieu de fichiers par fichiers sera bientôt disponible :
Voir [ANNONCE] Git 1.7.11.rc1 :

" git difftool " a appris le " --dir-diff option " pour lancer des outils de diff externes qui peuvent comparer deux hiérarchies de répertoires à la fois après avoir rempli deux répertoires temporaires, au lieu d'exécuter une instance de l'outil externe une fois par paire de fichiers .

Voir " Patch difftool Enseignements difftool pour gérer les différences de répertoire ", et la réponse " Comparaison des répertoires des branches Git "pour plus de détails.


Difftool original par répertoires script (décembre 2009)

Comme Seba Illingworth mentions dans sa réponse un script git-diffall.sh (également placé dans le chemin) peut faire exactement cela :

#!/bin/sh
git diff --name-only "$@" | while read filename; do
    git difftool "$@" --no-prompt "$filename" &
done

Mais cela ne fonctionne qu'en ouvrant n Windows pour n (si vous essayez d'utiliser les fichiers -s de WinMerge, cela ne fonctionnera pas car les fichiers temporaires seront supprimés trop tôt par l'outil de comparaison).


C'est pourquoi j'aime l'approche de GitDiff.bat - la diffusion en puissance avec GI qui vous permet de passer en revue la liste des fichiers présentant une différence, avant d'en sélectionner un pour examiner ses différences internes.
Je l'ai modifié pour qu'il n'utilise que des commandes DOS.

@echo off

setlocal

if "%1" == "-?" (
    echo GitDiff - enables diffing of file lists, instead of having to serially
    echo diff files without being able to go back to a previous file.
    echo Command-line options are passed through to git diff.
    echo If GIT_FOLDER_DIFF is set, it is used to diff the file lists. Default is windff.
    goto END
)

if "%GIT_DIFF_COPY_FILES%"=="" (
    rd /s /q %TEMP%\GitDiff
    mkdir %TEMP%\GitDiff
    mkdir %TEMP%\GitDiff\old
    mkdir %TEMP%\GitDiff\new

    REM This batch file will be called by git diff. This env var indicates whether it is
    REM being called directly, or inside git diff
    set GIT_DIFF_COPY_FILES=1

    set GIT_DIFF_OLD_FILES=%TEMP%\GitDiff\old
    set GIT_DIFF_NEW_FILES=%TEMP%\GitDiff\new

    set GIT_EXTERNAL_DIFF=%~dp0\GitDiff.bat
    echo Please wait and press q when you see "(END)" printed in reverse color...
    call git diff %*

    if defined GIT_FOLDER_DIFF (
        REM This command using GIT_FOLDER_DIFF just does not work for some reason.
        %GIT_FOLDER_DIFF% %TEMP%\GitDiff\old %TEMP%\GitDiff\new
        goto END
    )

    if exist "%ProgramFiles%\Beyond Compare 2\BC2.exe" (
        set GIT_FOLDER_DIFF="%ProgramFiles%\Beyond Compare 2\BC2.exe"
        "%ProgramFiles%\Beyond Compare 2\BC2.exe" %TEMP%\GitDiff\old %TEMP%\GitDiff\new
        goto END
    )

    "%ProgramFiles(x86)%\WinMerge\WinMergeU.exe" -r -e -dl "Local" -dr "Remote"  %TEMP%\GitDiff\old %TEMP%\GitDiff\new
    goto END
)

REM diff is called by git with 7 parameters:
REM     path old-file old-hex old-mode new-file new-hex new-mode
copy %TEMP%\%~nx2 %GIT_DIFF_OLD_FILES%\%1
copy %5 %GIT_DIFF_NEW_FILES%

:END

Il n'est pas assez robuste pour gérer des fichiers ayant le même nom dans différents répertoires, mais il vous donne une idée générale de ce qui est possible :
Ici, un seul WinMerge s'ouvrira, avec la liste des fichiers ayant des différences internes. Vous pouvez cliquer sur ceux que vous voulez examiner, puis un simple ESC fermera le tout WinMerge-diff session.

1 votes

J'essaie ceci avec la version 1.6.5.1.1367.gcd48 de git et il ne semble pas générer de fichiers dans ces dossiers temporaires. Une idée de l'endroit où chercher le problème ? Merci !

0 votes

@Art : dans ces cas de débogage, j'essaie d'isoler le problème en simplifiant le script : 1/ si le script est appelé avec le 7ème paramètre (première passe de git diff, pour copier les fichiers) 2/ est-ce que le script est au moins rappelé à la fin de l'opération d'extraction de l'information. git diff ?

0 votes

J'ai donc essayé ceci et cela ne fonctionne pas pour moi (version git 1.7.2.3). echo Launching WinMergeU.exe: $1 $2 fonctionne, un exemple de sortie est Launching WinMergeU.exe: /tmp/waxdnW_makeHTML.cfm scheduler/makeHTML.cfm mais je ne vois jamais ce dossier "tmp" et avec le lancement de winmerge la valeur de gauche est " C:\ColdFusion8\wwwroot\archiver -git \scheduler\makeHTML.cfm "mais la bonne valeur est vide et je ne peux pas appuyer sur "ok".

21voto

Gopi Points 173

J'ai rencontré des problèmes en utilisant la première partie à 2 endroits et je l'ai corrigée comme suit

  1. La deuxième commande pour configurer winmerge.cmd nécessitait un slash supplémentaire sur cmdline (avant $LOCAL et $REMOTE), sinon cygwin substituait la variable dans cmdline

    C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"\$LOCAL\" \"\$REMOTE\""
  2. j'ai changé le fichier winmerge.sh en (sans cela, j'obtenais l'erreur right-path-invalid)

    #!/bin/sh
    echo Launching WinMergeU.exe: "$(cygpath -aw "$1")" "$(cygpath -aw "$2")"
    "$PROGRAMFILES/WinMerge/WinMergeU.exe" -e -ub -dl "Base" -dr "Mine" "$(cygpath -aw "$1")" "$(cygpath -aw "$2")"

3 votes

J'ai suivi exactement les instructions de VonC, mais je recevais des arguments vides dans mon script de winmerge.sh. L'utilisation de barres obliques supplémentaires a résolu le problème. Merci !

9voto

John Bentley Points 149

Sans configuration :

git difftool --tool winmerge

Assumant :

  • Winmerge est installé
  • Git pour Windows est installé, à partir de "git version 2.12.0.windows1" ou plus (bien que des versions antérieures de git aient pu introduire la commande).

1 votes

Merci, c'est la solution la plus simple

8voto

Caner Points 15625

Sous Windows, vous pouvez procéder de cette manière :

1) Ouvrez le fichier .gitconfig. Il est situé dans votre répertoire personnel : c : \users\username.gitconfig

2) Ajoutez les lignes ci-dessous. Faites attention aux guillemets simples qui entourent le chemin vers winmerge :

[diff]
    tool = winmerge
[difftool "winmerge"]
    cmd = "'C:/Program Files (x86)/WinMerge/WinMergeU.exe'" -e "$LOCAL" "$REMOTE"
[difftool]
    prompt = false
[merge]
    tool = winmerge
[mergetool "winmerge"]
    cmd = "'C:/Program Files (x86)/WinMerge/WinMergeU.exe'" \"$MERGED\" \"$REMOTE\"
[mergetool]
    keepBackup = false
    trustExitCode = false

0 votes

Faites également attention à la avant des barres obliques au lieu des barres obliques inverses dans le chemin de la commande.

7voto

Alf47 Points 473

J'ai un script qui définira les outils Diff et Merge dans la configuration Git avec les paramètres appropriés qui ne nécessitent pas l'existence d'un fichier .sh séparé. Cela semble fonctionner correctement pour moi.

git config --global diff.tool winmerge
git config --global difftool.prompt false
git config --global difftool.winmerge.cmd "\"\$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\""

git config --global merge.tool winmerge
git config --global mergetool.prompt false
git config --global mergetool.winmerge.trustExitCode true
git config --global mergetool.winmerge.cmd "\"\$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\" \"\$BASE\" \"\$MERGED\""

Note - toute la partie .cmd est citée afin que les paramètres soient correctement listés dans le .gitconfig.

1 votes

La commande suivante n'a pas fonctionné pour moi. git config --global difftool.winmerge.cmd "\"\$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\"" Remarque : Cette commande doit être exécutée à partir d'une invite de commande et non de powershell. J'ajoute manuellement les éléments suivants à mon fichier .gitconfig [difftool "winmerge"] La section a fonctionné pour moi : cmd = 'C:/Program Files (x86)/WinMerge/WinMergeU.exe' -r -u -e -dl \"Local\" -dr \"Remote\" \"$LOCAL\" \"$REMOTE\"

1 votes

Cela ne marchait pas, mais avec quelques modifications, cela fonctionne : ouvrez cmd en tant qu'administrateur, et exécutez : git config --global mergetool.winmerge.cmd "\"C:\Program Files (x86)\WinMerge\WinMergeU.exe\" -r -u -e -dl \"Local\" -dr \"Remote\" \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$MERGED\"" . Il y a eu quelques chaînes échappées incorrectes (notez quelques antislashs supplémentaires non désirés juste avant l'élément $ - Je suppose $ n'ont pas besoin d'être échappés). De plus, il manquait une fin " après WinMergeU?.exe . Exécuter git config --get mergetool.winmerge.cmd pour voir ce qui avait été effectivement fixé. Quoi qu'il en soit, merci pour le non .sh version : +1 !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X