Pregunta ¿Cómo veo la salida 'git diff' con mi herramienta / visor de diferencias preferido?


Cuando escribo git diff, Quiero ver el resultado con mi herramienta visual diff de elección (SourceGear "diffmerge" en Windows). ¿Cómo configuro git para hacer esto?


679
2017-10-31 22:55


origen


Respuestas:


Desde Git1.6.3, puedes usar script de git difftool: ver mi respuesta a continuación.


Tal vez esto artículo Te ayudará. Estas son las mejores partes:

Hay dos formas diferentes de especificar una herramienta de diferencia externa.

El primero es el método que usaste, configurando la variable GIT_EXTERNAL_DIFF. Sin embargo, se supone que la variable apunta a la ruta completa del ejecutable. Además, el ejecutable especificado por GIT_EXTERNAL_DIFF se invocará con un conjunto fijo de 7 argumentos:

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

Como la mayoría de las herramientas de diferencias requerirán un orden diferente (y solo algunos) de los argumentos, lo más probable es que tengas que especificar un script de envoltura, que a su vez llama a la herramienta de diferencia real.

El segundo método, que prefiero, es configurar la herramienta externa diff a través de "git" config ". Aquí esta lo que hice:

1) Cree un script de envoltura "git-diff-wrapper.sh" que contenga algo así como

-->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)--

Como puede ver, solo los argumentos segundo ("archivo antiguo") y quinto ("archivo nuevo") serán pasó a la herramienta diff.

2) Tipo

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

en el símbolo del sistema, reemplazando con la ruta a "git-diff-wrapper.sh", por lo que su ~ / .gitconfig contiene

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

Asegúrese de utilizar la sintaxis correcta para especificar las rutas de acceso al script de envoltura y diff herramienta, es decir, use barras oblicuas hacia adelante en lugar de hacia atrás. En mi caso, tengo

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

en .gitconfig y

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

en la secuencia de comandos envoltura. ¡Cuidado con el "gato" final!

(Supongo que el '| cat'solo es necesario para algunos programas que pueden no devolver un estado de devolución correcto o consistente. Es posible que desee probar sin el gato final si su herramienta diff tiene el estado de devolución explícita)


Eso (el artículo citado anteriormente) es la teoría de la herramienta externa definido a través del archivo de configuración (no a través de la variable de entorno).
En la práctica (aún para la definición del archivo de configuración de la herramienta externa), puede consultar:


366
2017-10-31 23:03



Para completar mi anterior respuesta de configuración "diff.external" encima:

Como mencionado por Jakub, Se introdujo Git1.6.3 git difftool, originalmente propuesto en septiembre de 2008:

USO ='[--tool=tool] [--commit=ref] [--start=ref --end=ref] [--no-prompt] [file to merge]'
(Ver --extcmd en la última parte de esta respuesta)

$LOCAL contiene el contenido del archivo de la revisión inicial y $REMOTE contiene el contenido del archivo en la revisión final.
$BASE contiene el contenido del archivo en el wor

Básicamente git-mergetool modificado para operar en el índice git / worktree.

El caso de uso habitual para este script es cuando tiene cambios por etapas o sin instancia y le gustaría ver los cambios en un visor de diferencias uno al lado del otro (p. xxdiff, tkdiff, etc.)

git difftool [<filename>*]

Otro caso de uso es cuando le gustaría ver la misma información, pero está comparando las confirmaciones arbitrarias (esta es la parte donde el análisis revarg podría ser mejor)

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

El último caso de uso es cuando desea comparar su árbol de trabajo actual con algo que no sea HEAD (por ejemplo, una etiqueta)

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

Nota: desde Git 2.5, git config diff.tool winmerge ¡es suficiente!
Ver "git mergetool winmerge"

Y desde Git 1.7.11, tienes la opción --dir-diff, para generar herramientas de diferencias externas que puedan comparar dos jerarquías de directorios a la vez después de rellenar dos directorios temporales, en lugar de ejecutar una instancia de la herramienta externa una vez por cada par de archivos.


Antes de Git 2.5:

Caso práctico para configurar difftool con su herramienta personalizada diff:

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

Con winmerge.sh almacenado en una parte del directorio de tu RUTA:

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

Si tiene otra herramienta (kdiff3, P4Diff, ...), cree otro script de shell y el apropiado difftool.myDiffTool.cmd directiva de configuración.
Entonces puede cambiar fácilmente las herramientas con el diff.tool config.

También tienes esto entrada de blog de Dave para agregar otros detalles.
(O esta pregunta Para el winmergeu opciones)

El interés con esta configuración es el winmerge.shguión: puede personalizarlo para tener en cuenta casos especiales.

Ver por ejemplo David Marblees Responda abajo para un ejemplo que trata con:

  • nuevo archivos en origen o destino
  • remoto archivos en origen o destino

Como Kem Mason menciona en su respuesta, tú también puedes evitar cualquier envoltorio mediante el uso de la --extcmd opción:

--extcmd=<command>

Especifique un comando personalizado para ver diffs. git-difftool ignora los valores predeterminados configurados y se ejecuta $command $LOCAL $REMOTE cuando se especifica esta opción.

Por ejemplo, así es como gitk es capaz de ejecutar / usar cualquier diff herramienta.


195
2018-06-04 08:25



En el espíritu de responder preguntas que son algo diferentes a las preguntas. Prueba esta solución:

$ meld my_project_using_git

Meld entiende git y proporciona navegación alrededor de los cambios recientes.


105
2018-03-14 16:28



Desde la versión 1.6.3 de Git, hay "git difftool"que puede configurar para usar su herramienta de diferencias gráfica favorita. Actualmente compatibles con la versión anterior son kdiff3, kompare, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, difuso y opendiff; si la herramienta que desea utilizar no está en esta lista, siempre puede usar 'difftool.<tool>.cmd'opción de configuración.

"git difftool" acepta las mismas opciones que "git diff".


38
2018-05-23 11:37



Con nuevo git difftool, es tan simple como agregar esto a su .gitconfig archivo:

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

También echa un vistazo Diffall, un script simple que escribí para extender el molesto comportamiento de diferencia (IMO) de abrir cada uno en serie.


34
2017-08-27 09:39



Tengo una adición a esto. Me gusta utilizar regularmente una aplicación de diferencias que no es compatible como una de las herramientas predeterminadas (por ejemplo, caleidoscopio), a través de

git difftool -t

También me gusta tener el valor predeterminado diff simplemente sea la línea de comando regular, por lo que configurar el GIT_EXTERNAL_DIFF variable no es una opción.

Puedes usar un arbitrario diff aplicación como una sola vez con este comando:

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

Simplemente pasa los 2 archivos al comando que especifiques, por lo que probablemente tampoco necesites un contenedor.


21
2018-02-03 00:16



Basándose en la respuesta de VonC para tratar con eliminaciones y adiciones de archivos, use los siguientes comandos y scripts:

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

Que es lo mismo que poner esto en su global .gitconfig:

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

Luego ponga lo siguiente en winmerge.shque debe estar en tu camino:

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



Solución para Windows / msys git

Después de leer las respuestas, descubrí una manera más simple que implica cambiar solo un archivo.

  1. Cree un archivo por lotes para invocar su programa diff, con el argumento 2 y 5. Este archivo debe estar en algún lugar de su ruta. (Si no sabe dónde está eso, colóquelo en c: \ windows). Llámalo, por ejemplo, "gitdiff.bat". El mio es:

    @echo off
    REM This is gitdiff.bat
    "C:\Program Files\WinMerge\WinMergeU.exe" %2 %5
    
  2. Establezca la variable de entorno para que apunte a su archivo por lotes. Por ejemplo:GIT_EXTERNAL_DIFF=gitdiff.bat. O a través de powershell escribiendo git config --global diff.external gitdiff.bat.

    Es importante no utilizar comillas o especificar ninguna información de ruta; de lo contrario, no funcionará. Es por eso que gitdiff.bat debe estar en tu camino.

Ahora cuando escribe "git diff", invocará su visor de diferencias externo.


10
2018-02-21 19:10



Si estás haciendo esto a través de cygwin, es posible que necesites usar cygpath:

$ git config difftool.bc3.cmd "git-diff-bcomp-wrapper.sh \$LOCAL \$REMOTE"
$ cat git-diff-bcomp-wrapper.sh
#!/bin/sh
"c:/Program Files (x86)/Beyond Compare 3/BComp.exe" `cygpath -w $1` `cygpath -w $2`

8
2018-03-30 17:42



esto funciona para mí en Windows 7. No hay necesidad de scripts intermedios sh

contenidos de .gitconfig:

    [diff]
      tool = kdiff3

    [difftool]
       prompt = false

    [difftool "kdiff3"]
      path = C:/Program Files (x86)/KDiff3/kdiff3.exe
      cmd = "$LOCAL" "$REMOTE"

7
2018-02-02 21:26



Un breve resumen de las excelentes respuestas anteriores:

git difftool --tool-help
git config --global diff.tool <chosen tool>
git config --global --add difftool.prompt false

Luego úsala escribiendo (opcionalmente especificando también el nombre del archivo):

git difftool

7
2017-11-04 10:36