web-dev-qa-db-fra.com

utiliser Winmerge à l'intérieur de Git pour classer diff

Est-il possible d’utiliser Winmerge à l’intérieur de git pour faire des diffs? 

96
eiu165

Mise à jour juin 2015, 6 ans plus tard:

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

Git 2.5+ (Q2, 2015) est maintenant conscient de Winmerge en tant qu'outil de différenciation ou de fusion!


Réponse originale (2009-2012)

(msysgit, 1.6.5, session DOS)

La première partie (utilisant winmerge) est décrite dans " Comment afficher la sortie" git diff "avec un programme visuel 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 une partie du répertoire de votre PATHname__:

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

(voir Options de ligne de commande WinMerge )

git difftool

va maintenant lancer WinMerge.
Si vous souhaitez que git diff lance WinMerge, définissez simplement:

set GIT_EXTERNAL_DIFF=winmerge.sh

Mais la véritable valeur ajoutée provient de la possibilité d’utiliser ce même outil de différenciation pour présenter toutes les différences en un seul lot au lieu de les présenter de manière séquentielle, ce qui vous oblige à fermer. l'outil diff ouvre un fichier à la fois.

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

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

"git difftool" a appris l'option "--dir-diff" pour créer des outils de différenciation externes pouvant 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 difftoolname__: teach difftoolpour gérer les différences de répertoire", et la réponse " Comparaison de répertoire de Git branches "pour plus de détails.


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

Comme Seba Illingworth mentionne 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 que si vous ouvrez n fenêtres pour n fichiers (si vous essayez d’utiliser l’option -s de WinMerge, elle ne sera pas utilisée. travail parce que les fichiers temporaires ont été supprimés trop tôt par difftool)


C'est pourquoi j'apprécie l'approche de GitDiff.bat - power-diffing with GI , qui vous permet de réviser la liste des fichiers avec une différence, avant de choisir celui qui examine ses différences internes.
Je l'ai modifié pour utiliser uniquement les 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 portant le même nom dans des répertoires différents, mais cela vous donne une idée générale de ce qui est possible:
Ici, un seul WinMerge s’ouvrira, la liste des fichiers présentant des différences internes. Vous pouvez cliquer sur ceux que vous voulez examiner, puis un simple ESC ferme la session WinMerge-diff.

112
VonC

J'ai eu du mal à utiliser la première partie à 2 endroits et je l'ai fixée comme suit

  1. La deuxième commande pour configurer winmerge.cmd nécessitait une barre oblique supplémentaire sur la ligne de commande (avant $ LOCAL et $ REMOTE), sinon cygwin remplaçait la variable dans la ligne de commande

    C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"\$LOCAL\" \"\$REMOTE\""
    
  2. changé le fichier winmerge.sh en (sans cela, l'erreur devenait 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")"
    
19
Gopi

J'ai un script qui va définir 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 bien fonctionner 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\""

Remarque - l'intégralité de la partie .cmd est citée de sorte que les paramètres soient correctement répertoriés dans le fichier .gitconfig

6
Alf47

Comme le thread est en train de devenir confus et bifurqué, voici les instructions consolidées pour la méthode WinMerge de la liste des répertoires "--dir-diff" pour msysgit Git Windows.

Étape 1 - Créez un fichier nommé winmerge.sh à un emplacement accessible par votre chemin (tel que /home/bin/winmerge.sh) avec le contenu suivant.

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

Étape 2 - Tapez les commandes suivantes dans Git Bash pour indiquer à git d'utiliser winmerge.sh comme difftool (ces options sont stockées dans /home/.gitconfig):

git config --replace --global diff.tool winmerge
git config --replace --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\""
git config --replace --global difftool.Prompt false

Étape 3 - Vous pouvez maintenant tester en tapant la commande suivante dans Git Bash pour démarrer votre diff WinMerge:

git difftool --dir-diff

Étape 4 - Pour un accès plus rapide, créez un alias pour cette commande en ajoutant cette ligne à .bashrc dans votre dossier personnel (ou créez un fichier .bashrc avec cette ligne si le fichier n'existe pas déjà):

alias diffdir='git difftool --dir-diff'

Étape 5 - Vous pouvez maintenant voir rapidement un diff dans WinMerge simplement en tapant la commande suivante dans Git Bash

diffdir
6
robertcollier4

Sans configuration:

git difftool --tool winmerge

En supposant:

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

Sur Windows, vous pouvez le faire de cette façon:

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

2) Ajoutez les lignes ci-dessous. Faites attention aux guillemets simples qui enveloppent le chemin du 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
2
Caner

Je ne comprenais pas pourquoi la solution était présentée sous forme de fichier de commandes DOS, mon installation de Git étant livrée avec un shell bash. Je ne pouvais pas non plus exécuter un contexte DOS à partir de bash. J'ai donc essayé d'adapter ce qui était précédemment partagé dans un contexte bash.

Puisque git diff semble exécuter la commande spécifiée une fois pour chaque fichier, j'ai scindé ma solution en deux scripts bash:

Tout d’abord, configurez gitprepdiff.sh pour qu’il soit l’outil difftool mentionné précédemment

#!/bin/sh
#echo ...gitprepdiff.sh
cp -v $1 "$TMP/GitDiff/old/$2"
cp -v $2 "$TMP/GitDiff/new"

J'ai également noté que les résultats des commandes git configure peuvent être trouvés et modifiés directement dans C:\Users\<username>\.gitconfigure

gitdiff.sh est ensuite exécuté sur la ligne de commande où vous appelez normalement git diff

#!/bin/sh
#echo Running gitdiff.sh...

DIFFTEMP=$TMP/GitDiff

echo Deleting and re-creating $DIFFTEMP...
rm -rf $DIFFTEMP;
mkdir $DIFFTEMP;

echo Creating $DIFFTEMP/old...
mkdir $DIFFTEMP/old;

echo Creating $DIFFTEMP/new...
mkdir $DIFFTEMP/new;

git diff --name-only "$@" | while read filename; do
    git difftool "$@" --no-Prompt "$filename";
done

"$PROGRAMFILES\WinMerge\WinMergeU.exe" -r -e -dl "Repository" -dr "Working" $LOCALAPPDATA\\Temp\\1\\GitDiff\\old $LOCALAPPDATA\\Temp\\1\\GitDiff\\new

Il est également intéressant de noter que, sur mon installation, /tmp (en bash) a été mappé à %LOCALAPPDATA%\Temp\1\ (sous Windows), c'est pourquoi j'utilise ce dernier dans mon appel à WinMerge.

2
Shawn South
git config --global diff.tool winmerge
git config --global difftool.winmerge.cmd "\"$PROGRAMFILES\\WinMerge\\WinMergeU.exe\" -u -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\""
git config --global difftool.Prompt false

Selon le manuel de la ligne de commande WinMerge : "Les paramètres sont préfixés par une barre oblique (/) ou un tiret (-)"

1
Steve Lang