Pregunta

¿Hay alguna manera de usar Winmerge dentro de git para hacer diferencias?

¿Fue útil?

Solución

Actualización de junio de 2015, 6 años después:

Como se detalla en "git mergetool winmerge", un simple git config diff.tool winmerge será suficiente.

¡Git 2.5+ (segundo trimestre de 2015) ahora reconoce Winmerge como una herramienta de comparación o combinación!


Respuesta original (2009-2012)

(msysgit, 1.6.5, sesión de DOS)

La primera parte (usando winmerge) se describe en "¿Cómo veo la salida de 'git diff' con el programa 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

Con winmerge.sh almacenado en un directorio que forma parte de su PATH:

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

(ver Opciones de línea de comandos de WinMerge)

git difftool

Ahora iniciará WinMerge.
Si quieres git diff para iniciar WinMerge, simplemente configure:

set GIT_EXTERNAL_DIFF=winmerge.sh

Pero el verdadero valor agregado proviene de la capacidad de utilizar esa misma herramienta de comparación para presentar todas las diferencias en un lote en lugar de presentarlos secuencialmente, lo que le obligará a cerrar las ventanas de la herramienta de diferencias, un archivo a la vez.

Actualización de junio de 2012 (2 años y medio después):

Próximamente estará disponible la comparación de directorios en lugar de archivo por archivo:
Ver [ANUNCIO] Git 1.7.11.rc1:

"git difftool"aprendí el"--dir-diff"Opción para generar herramientas de diferenciación externas que pueden comparar dos jerarquías de directorios a la vez después de llenar dos directorios temporales, en lugar de ejecutar una instancia de la herramienta externa una vez por par de archivos.

Ver "Parche difftool:enseñar difftool para manejar diferencias de directorio", y la respuesta"Comparación de directorios de sucursales de Git" para más detalles.


Guión original de difftool by directorios (diciembre de 2009)

Como Seba Illingworth menciona en su respuesta, un script git-diffall.sh (también incluido en la ruta) puede hacer precisamente eso:

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

Pero eso solo funciona abriendo norte ventanas para norte archivos (si intenta utilizar el -s opción de WinMerge, no funcionará debido a que difftool elimina los archivos temporales demasiado pronto)


Por eso me gusta el enfoque de GitDiff.bat: diferenciación de potencia con GI, que le permite revisar la lista de archivos con una diferencia, antes de seleccionar uno para examinar sus diferencias internas.
Lo he modificado para usar sólo comandos de 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

No es lo suficientemente robusto como para manejar archivos con el mismo nombre en diferentes directorios, pero le da una idea general de lo que es posible:
Aquí solo se abrirá un WinMerge, con la lista de archivos con diferencias internas.Puede hacer clic en los que desea examinar, luego un simple ESC cerrará todo WinMerge-diff sesión.

Otros consejos

I enfrentaron problemas para usar la primera parte en 2 lugares y se fija de la siguiente manera

  1. El segundo comando para configurar winmerge.cmd requiere una barra extra en cmdline (antes $ local y $ REMOTO), de lo contrario cygwin estaba sustituyendo la variable en línea_de_órdenes

    C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"\$LOCAL\" \"\$REMOTE\""
    
  2. cambia el archivo de winmerge.sh para (sin que esto, era conseguir la derecha de la ruta no válida-error)

    #!/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")"
    

Dado que el hilo se está confuso y bifurcada, las instrucciones aquí están consolidadas, para el listado del directorio "--dir-diff" WinMerge método para msysgit Git de Windows.

Paso 1 -. Crear un archivo llamado winmerge.sh en un lugar accesible a su trayectoria (como /home/bin/winmerge.sh) con el siguiente contenido

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

Paso 2 - Escriba los siguientes comandos en Git Bash para instruir a utilizar git winmerge.sh como difftool (estas opciones se almacenan en /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

Paso 3 - Ahora puede probar escribiendo el siguiente comando en Git Bash para iniciar su diff WinMerge:

git difftool --dir-diff

Paso 4 - Para un acceso más rápido, crear un alias para este comando añadiendo esta línea a .bashrc en su carpeta de inicio (o crear el archivo .bashrc con esta línea si el archivo no existe ya) :

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

Paso 5: - Ahora se puede ver rápidamente un diff en WinMerge simplemente escribiendo el siguiente comando en Git Bash

diffdir

Tengo un script que va a establecer el Dif y combinar herramientas en la configuración de Git con los parámetros adecuados que no requiere un archivo .sh separada de existir. Parece estar funcionando bien para mí.

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\""

Nota: - toda la parte .cmd es citado de manera que los parámetros se enumeran en la .gitconfig correctamente

En Windows, puede hacerlo de esta manera:

1) Abrir el archivo .gitconfig. Está situado en el directorio de inicio: C: \ Users \ username.gitconfig

2) Añadir las siguientes líneas. Prestar atención a las comillas simples que envuelven el camino a 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

Sin configuración:

git difftool --tool winmerge

Suponiendo:

  • Winmerge se instala
  • Git para Windows está instalado, de "versión git 2.12.0.windows1" o superior (aunque las versiones anteriores de git pueden haber introducido el comando).

Yo estaba confundido acerca de por qué la solución se presenta como un archivo por lotes de DOS, como la instalación de Git vino con un shell bash. También era incapaz de conseguir un contexto de DOS corriendo de fiesta, así que he intentado adaptar lo que fue compartido previamente en un contexto bash.

Desde git diff aparece para ejecutar el comando especificado una vez por cada archivo, he dividido mi solución en dos scripts bash:

En primer lugar, configurar gitprepdiff.sh ser el difftool como se mencionó anteriormente

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

I observó también que los resultados de los comandos git configure se pueden encontrar y editar directamente en C:\Users\<username>\.gitconfigure

gitdiff.sh continuación, se ejecuta en la línea de comandos donde normalmente llamar 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

También digno de mención es que, en mi instalación, /tmp (en bash) asignada a %LOCALAPPDATA%\Temp\1\ (en Windows), así que por eso estoy usando este último en mi llamada a WinMerge.

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

De acuerdo con la WinMerge línea de comandos instrucciones de uso "Parámetros tienen el prefijo una barra diagonal ( /) o un guión (-) carácter "

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top