¿Cómo veo la salida 'git diff' con un progtwig visual diff?

Cuando 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?

Desde Git1.6.3, puede usar el script git difftool : vea mi respuesta a continuación .


Puede ser que este artículo te ayude. Estas son las mejores partes:

Hay dos forms 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 set fijo de 7 arguments:

 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 order diferente (y solo algunos) de los arguments, 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 el segundo ("file antiguo") y el quinto ("nuevo file") se pasarán 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 usar la syntax correcta para especificar las routes de acceso a la herramienta script y diff del wrapper, es decir, use slashed forward en lugar de barras invertidas. 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 commands envoltura. ¡Cuidado con el "gato" final!

(Supongo que el ' | cat ' es necesario solo para algunos progtwigs 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 un estado de devolución explícito)


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

  • ¿Cómo configuro DiffMerge con msysgit / gitk? que ilustra la configuration concreta de DiffMerge y WinMerge para MsysGit y gitk
  • ¿Cómo puedo configurar un editor para trabajar con Git en Windows? para la definición de Notepad ++ como editor externo.

Para completar mi respuesta de configuration anterior "diff.external" más arriba:

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

USAGE = '[--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 file de la revisión inicial y $REMOTE contiene el contenido del file en la revisión final.
$BASE contiene el contenido del file en el wor

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

El caso de uso habitual para esta secuencia de commands es cuando tiene cambios escalonados o no escalonados y le gustaría ver los cambios en un visor de diff lado a lado (por ejemplo, tkdiff , 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 de revarg podría ser mejor)

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

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

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

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


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 directory 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 otra secuencia de commands de shell y la correspondiente directiva difftool.myDiffTool.cmd config.
Luego puede cambiar fácilmente las herramientas con la configuration diff.tool .

También tiene esta input de blog de Dave para agregar otros detalles.
(O esta pregunta para las opciones de winmergeu )

El interés con esta configuration es el script winmerge.sh : puede personalizarlo para tener en count casos especiales.

Véase, por ejemplo, la respuesta de David Marble a continuación para un ejemplo que trata de:

  • nuevos files en origen o destino
  • files eliminados en origen o destino

Como Kem Mason menciona en su respuesta , también puedes evitar cualquier envoltorio usando la opción --extcmd :

 --extcmd=<command> 

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

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

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 navigation alnetworkingedor de los cambios recientes.

Desde la versión 1.6.3 de git, hay " git difftool " que puedes configurar para usar tu herramienta favorita de diferencias gráficas. Actualmente compatibles con out-of-the-box son kdiff3, kompare, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, diffuse y opendiff ; si la herramienta que desea utilizar no está en esta list, siempre puede usar la opción de configuration ' difftool.<tool>.cmd '.

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

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

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

También mire hacia fuera el error , un script simple que escribí para extender el molesto comportamiento de diferencia (IMO) de abrir cada uno en serie.

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

 git difftool -t 

También me gusta que la diff pnetworkingeterminada sea la línea de command normal, por lo que establecer la variable GIT_EXTERNAL_DIFF no es una opción.

Puede utilizar una aplicación arbitraria diff como una aplicación única con este command:

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

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

Basándose en la respuesta de VonC para tratar con eliminaciones y adiciones de files, use los siguientes commands 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 

Lo cual es lo mismo que poner esto en tu .gitconfig global:

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

A continuación, coloque lo siguiente en winmerge.sh que debe estar en su ruta:

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

Solución para Windows / msys git

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

  1. Cree un file por lotes para invocar su progtwig diff, con el argumento 2 y 5. Este file 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 file 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 path.

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

Si está haciendo esto a través de cygwin, es posible que necesite 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` 

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" 

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

 git difftool 

Introducción

Como reference, me gustaría include mi variación en la respuesta de VonC. Tenga en count que estoy usando la versión MSys de Git (1.6.0.2 en este momento) con PATH modificada, y ejecutando Git de Powershell (o cmd.exe), no el shell Bash.

Introduje un nuevo command, gitdiff . Al ejecutar este command, se networkingirige temporalmente a git diff para usar un progtwig de diferencia visual de su elección (a diferencia de la solución de VonC que lo hace de forma permanente). Esto me permite tener tanto la funcionalidad de diferencia de Git por defecto ( git diff ) como la funcionalidad de diferencia visual ( gitdiff ). Ambos commands toman los mismos parameters, por lo que, para diferenciar visualmente los cambios en un file en particular, puede escribir

 gitdiff path/file.txt 

Preparar

Tenga en count que $GitInstall se usa como marcador de position para el directory donde está instalado Git.

  1. Crea un nuevo file, $GitInstall\cmd\gitdiff.cmd

     @echo off setlocal for /F "delims=" %%I in ("%~dp0..") do @set path=%%~fI\bin;%%~fI\mingw\bin;%PATH% if "%HOME%"=="" @set HOME=%USERPROFILE% set GIT_EXTERNAL_DIFF=git-diff-visual.cmd set GIT_PAGER=cat git diff %* endlocal 
  2. Cree un nuevo file, $GitInstall\bin\git-diff-visual.cmd (reemplazando el marcador de position [visual_diff_exe] con la ruta completa al progtwig diff de su elección)

     @echo off rem diff is called by git with 7 parameters: rem path old-file old-hex old-mode new-file new-hex new-mode echo Diffing "%5" "[visual_diff_exe]" "%2" "%5" exit 0 
  3. Ya has terminado. La ejecución de gitdiff desde un repository de Git ahora debería invocar su progtwig visual diff para cada file que se haya cambiado.

Aquí hay un file de process por lotes que funciona para Windows: asume que DiffMerge está instalado en la location pnetworkingeterminada, maneja x64, maneja la sustitución de barras diagonales hacia atrás según sea necesario y tiene la capacidad de instalarse. Debería ser fácil replace DiffMerge con su progtwig favorito de diferencias.

Instalar:

 gitvdiff --install 

gitvdiff.bat:

 @echo off REM ---- Install? ---- REM To install, run gitvdiff --install if %1==--install goto install REM ---- Find DiffMerge ---- if DEFINED ProgramFiles^(x86^) ( Set DIFF="%ProgramFiles(x86)%\SourceGear\DiffMerge\DiffMerge.exe" ) else ( Set DIFF="%ProgramFiles%\SourceGear\DiffMerge\DiffMerge.exe" ) REM ---- Switch forward slashes to back slashes ---- set oldW=%2 set oldW=%oldW:/=\% set newW=%5 set newW=%newW:/=\% REM ---- Launch DiffMerge ---- %DIFF% /title1="Old Version" %oldW% /title2="New Version" %newW% goto :EOF REM ---- Install ---- :install set selfL=%~dpnx0 set selfL=%selfL:\=/% @echo on git config --global diff.external %selfL% @echo off :EOF 

Si estás en una Mac y tienes XCode, entonces tienes FileMerge instalado. El command del terminal es abierto, por lo que puedes hacer git difftool -t opendiff

Para get una versión de Linux de cómo configurar una herramienta diff en las versiones de git anteriores a la 1.6.3 (1.6.3 se agregó difftool a git) este es un gran tutorial conciso,

en breve:

Paso 1: agrégalo a tu .gitconfig

 [diff] external = git_diff_wrapper [pager] diff = 

Paso 2: crea un file llamado git_diff_wrapper, ponlo en algún lugar de tu $ PATH

 #!/bin/sh vimdiff "$2" "$5" 

Instalar meld

  # apt-get install meld 

Luego elige eso como difftool

  $ git config --global diff.tool meld 

Si desea ejecutarlo en el tipo de console:

  $ git difftool 

Si quiere usar el modo gráfico, escriba:

  $ git mergetool 

Y la salida sería:

  'git mergetool' will now attempt to use one of the following tools: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare emerge vimdiff Merging: www/css/style.css www/js/controllers.js Normal merge conflict for 'www/css/style.css': {local}: modified file {remote}: modified file Hit return to start merge resolution tool (meld): 

Tan solo presione enter para usar meld (pnetworkingeterminado), esto abriría el modo gráfico, hará que la magia se guarde y presione eso para resolver la fusión. Eso es todo

En Mac OS X,

 git difftool -t diffuse 

hace el trabajo por mí en la carpeta git. Para la installation difusa, uno puede usar el puerto –

 sudo port install diffuse 

Probé las cosas elegantes aquí (con tkdiff) y nada funcionó para mí. Entonces escribí el siguiente script, tkgitdiff. Hace lo que necesito que haga.

 $ cat tkgitdiff #!/bin/sh # # tkdiff for git. # Gives you the diff between HEAD and the current state of your file. # newfile=$1 git diff HEAD -- $newfile > /tmp/patch.dat cp $newfile /tmp savedPWD=$PWD cd /tmp patch -R $newfile < patch.dat cd $savedPWD tkdiff /tmp/$newfile $newfile 

puedes usar git difftool .

por ejemplo, si tiene meld , puede editar el branchs master y devel por:

 git config --global diff.external meld git difftool master..devel 

He estado usando este bit en ~/.gitconfig durante mucho time:

 [diff] external = ~/Dropbox/source/bash/git-meld 

Con git-meld :

 #!/bin/bash if [ "$DISPLAY" = "" ]; then diff $2 $5 else meld $2 $5 fi 

Pero ahora me cansé de usar siempre meld en el entorno gráfico, y no es trivial invocar el diff normal con esta configuration, así que cambié a esto:

 [alias] v = "!sh -c 'if [ $# -eq 0 ] ; then git difftool -y -t meld ; else git difftool -y $@ ; fi' -" 

Con esta configuration, cosas como esta funcionan:

 git v git v --staged git v -t kompare git v --staged -t tkdiff 

Y aún conservo el buen viejo git diff .

Después de mirar algunas otras herramientas de diferencias externas, encontré que la vista diff en IntelliJ IDEA (y Android Studio) es la mejor para mí.

Paso 1: configurar IntelliJ IDEA para que se ejecute desde la línea de command

Si desea utilizar IntelliJ IDEA como su herramienta de diferenciación, primero debe configurar IntelliJ IDEA para que se ejecute desde la línea de command siguiendo las instrucciones aquí :

En macOS o UNIX:

  1. Asegúrese de que IntelliJ IDEA se está ejecutando.
  2. En el menu principal, elija Tools | Create Command-line Launcher Tools | Create Command-line Launcher . Se abre el cuadro de dialog Crear secuencia de commands del iniciador, con la ruta sugerida y el nombre del script del iniciador. Puede aceptar valores pnetworkingeterminados o especificar su propia ruta. Notifíquelo, ya que lo necesitará más tarde. Fuera de IntelliJ IDEA, agregue la ruta y el nombre del script de inicio a su ruta.

En Windows:

  1. Especifique la location del ejecutable IntelliJ IDEA en la variable de entorno del sistema Path. En este caso, podrá invocar el ejecutable IntelliJ IDEA y otros commands IntelliJ IDEA desde cualquier directory.

Paso 2: configure git para usar IntelliJ IDEA como difftool

Siguiendo las instrucciones en esta publicación de blog :

Intento

 export INTELLIJ_HOME /Applications/IntelliJ\ IDEA\ CE.app/Contents/MacOS PATH=$IDEA_HOME $PATH 

Pescado

 set INTELLIJ_HOME /Applications/IntelliJ\ IDEA\ CE.app/Contents/MacOS set PATH $INTELLIJ_HOME $PATH 

Ahora agrega lo siguiente a tu configuration de git:

 [merge] tool = intellij [mergetool "intellij"] cmd = idea merge $(cd $(dirname "$LOCAL") && pwd)/$(basename "$LOCAL") $(cd $(dirname "$REMOTE") && pwd)/$(basename "$REMOTE") $(cd $(dirname "$BASE") && pwd)/$(basename "$BASE") $(cd $(dirname "$MERGED") && pwd)/$(basename "$MERGED") trustExitCode = true [diff] tool = intellij [difftool "intellij"] cmd = idea diff $(cd $(dirname "$LOCAL") && pwd)/$(basename "$LOCAL") $(cd $(dirname "$REMOTE") && pwd)/$(basename "$REMOTE") 

Puedes probarlo con git difftool o git difftool HEAD~1

Yo uso kompare en ubuntu:

 sudo apt-get install kompare 

Para comparar dos twigs:

 git difftool -t kompare <my_branch> master 

Si ya tiene una herramienta diff asociada con types de files (por ejemplo, porque instaló TortoiseSVN que viene con un visor de diferencias), puede canalizar la salida regular de git diff a un file "temp", luego simplemente abra ese file directamente sin necesidad para saber algo sobre el espectador:

 git diff > "~/temp.diff" && start "~/temp.diff" 

Establecerlo como un alias global funciona aún mejor: git what

 [alias] what = "!f() { git diff > "~/temp.diff" && start "~/temp.diff"; }; f" 

Si no eres uno para la línea de command, entonces si instalas tort git puedes hacer clic derecho sobre un file para get un submenu tortoisegit con la opción "Diff later".

Cuando selecciona esto en el primer file, puede hacer clic derecho en el segundo file, ir al submenu tortoisegit y seleccionar "Dif. Con == su file aquí ==" Esto le dará a la guía de tortoisegitmerge el resultado.

Es posible que desee probar xd http://github.com/jiqingtang/xd , que es envoltorio GUI para diferencias GIT / SVN. NO es una herramienta diff en sí misma. Ejecuta xd cuando quiere ejecutar git diff o svn diff y le muestra una list de files, una window de previsualización y puede ejecutar cualquier herramienta diff que le guste, incluyendo tkdiff, xxdiff, gvimdiff, emacs (ediff), xemacs ( ediff), meld, diffuse, kompare y kdiff3. También puede ejecutar cualquier herramienta personalizada.

Lamentablemente, la herramienta no es compatible con Windows.

Divulgación : soy el autor de esta herramienta.