Cuando git diff
escribo, quiero ver el resultado con mi herramienta de elección visual diff (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. Aquí están las mejores partes:
Hay dos formas diferentes de especificar una herramienta diff externa.
El primero es el método que utilizó, estableciendo 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 llamará 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 diff requerirán un orden diferente (y solo algunos) de los argumentos, lo más probable es que tengas que especificar un script envoltorio, que a su vez llama a la herramienta diff 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 contenedor "git-diff-wrapper.sh" que contenga algo 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") 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 utilizar la sintaxis correcta para especificar las rutas de acceso al script de envoltura y la herramienta de diferencias, es decir, utilice barras diagonales en lugar de barras diagonales inversas. 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 el script de envoltura. ¡Cuidado con el "gato" final!
(Supongo que ' | cat
' es necesario solo para algunos programas que pueden no devolver un estado de retorno adecuado o consistente. Es posible que desee probar sin el gato final si su herramienta diff tiene un estado de retorno explícito)
( Diomidis Spinellis agrega en los comentarios :
El
cat
comando es obligatorio porquediff(1)
, por defecto, sale con un código de error si los archivos difieren.
Git espera que el programa diff externo salga con un código de error solo si ocurrió un error real, por ejemplo, si se queda sin memoria.
Canalizando el resultado degit
quecat
el código de error no nulo está enmascarado.
Más eficientemente, el programa podría ejecutarseexit
con un argumento de 0).
Esa (el artículo citado anteriormente) es la teoría de la herramienta externa definida 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:
Para completar mi configuración anterior "diff.external", responda arriba:
Como lo mencionó Jakub , Git1.6.3 introdujo 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 desde la revisión inicial y $REMOTE
el contenido del archivo en la revisión final.
$BASE
contiene el contenido del archivo en el wor
Básicamente se
git-mergetool
modifica para operar en el índice git / worktree.El caso de uso habitual para este script es cuando tiene cambios escalonados o no escalonados y le gustaría ver los cambios en un visor de diferencias de lado a lado (p
xxdiff
. Ej .tkdiff
, Etc.).
git difftool [<filename>*]
Otro caso de uso es cuando desea ver la misma información pero está comparando confirmaciones arbitrarias (esta es la parte en la que 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 árbol de trabajo actual con algo diferente a 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 , tiene la opción --dir-diff
, para generar herramientas de diferencias 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 un par de archivos.
Antes de Git 2.5:
Caso práctico para configurar difftool
con su herramienta diff personalizada:
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 su 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 la difftool.myDiffTool.cmd
directiva de configuración adecuada .
Entonces puede cambiar fácilmente las herramientas con la diff.tool
configuración.
También tiene esta entrada de blog de Dave para agregar otros detalles.
(O esta pregunta para las winmergeu
opciones)
El interés con esta configuración es el winmerge.sh
script : puede personalizarlo para tener en cuenta casos especiales.
Vea, por ejemplo , la respuesta de David Marble a continuación para ver un ejemplo que trata:
Como Kem Mason menciona en su respuesta , también puede evitar cualquier envoltorio utilizando la --extcmd
opción :
--extcmd=<command>
Especifique un comando personalizado para ver las diferencias.
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
se puede ejecutar / usar cualquier diff
herramienta .
--start=
y --end=
no se reconocen en v1.7.11
En el espíritu de responder preguntas que son algo diferentes a las formuladas. Prueba esta solución:
$ meld my_project_using_git
Meld entiende git y proporciona navegación en torno a los cambios recientes.
meld .
que git difftool
y tener que ver los archivos modificados secuencialmente. Y está mucho más cerca del hg vdiff
complemento de Mercurial .
meld .
funciona en proyectos de Mercurial y Subversion, en caso de que alguien tenga curiosidad.
1.1.5
.
Con el nuevo git difftool , es tan simple como agregar esto a su archivo .gitconfig :
[diff]
tool = any-name
[difftool "any-name"]
cmd = "\"C:/path/to/my/ext/diff.exe\" \"$LOCAL\" \"$REMOTE\""
Opcionalmente, también agregue:
[difftool]
prompt = false
También echa un vistazo a diffall , un script simple que escribí para extender el molesto comportamiento de diferencia predeterminado (IMO) de abrir cada uno en serie.
Global .gitconfig en Windows está en %USERPROFILE%\.gitconfig
Desde la versión 1.6.3 de git, existe " git difftool ", que puede configurar para usar su herramienta gráfica de diferencia favorita. Actualmente se admiten de forma inmediata kdiff3, kompare, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, diffuse y opendiff ; Si la herramienta que desea usar no está en esta lista, siempre puede usar la difftool.<tool>.cmd
opción de configuración ' '.
"git difftool" acepta las mismas opciones que "git diff".
git difftool -t kdiff3 HEAD
Tengo una adición a esto. Me gusta usar regularmente una aplicación diff que no es compatible como una de las herramientas predeterminadas (por ejemplo, caleidoscopio), a través de
git difftool -t
También me gusta que el valor predeterminado diff
sea solo la línea de comando normal, por lo que configurar la GIT_EXTERNAL_DIFF
variable no es una opción.
Puede usar una diff
aplicación arbitraria como única con este comando:
git difftool --extcmd=/usr/bin/ksdiff
Simplemente pasa los 2 archivos al comando que especifique, por lo que probablemente tampoco necesite un contenedor.
--extcmd
opción. +1. Lo he incluido en mi respuesta.
Basándose en la respuesta de VonC para lidiar con las 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
Lo cual 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 el winmerge.sh
que debe estar en su 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
winmerge.sh
guión. +1. He actualizado mi respuesta para vincular a la suya.
winmerge.bat
en el segundo fragmento debe serwinmerge.sh
Después de leer las respuestas, descubrí una forma más simple que implica cambiar solo un archivo.
Cree un archivo por lotes para invocar su programa diff, con argumentos 2 y 5. Este archivo debe estar en algún lugar de su ruta. (Si no sabe dónde está, póngalo en c: \ windows). Llámelo, por ejemplo, "gitdiff.bat". El mio es:
@echo off
REM This is gitdiff.bat
"C:\Program Files\WinMerge\WinMergeU.exe" %2 %5
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 ni especificar ninguna información de ruta, de lo contrario no funcionará. Es por eso que gitdiff.bat debe estar en tu camino.
Ahora, cuando escriba "git diff", invocará su visor de diferencias externo.
git config --global diff.external winmerge.cmd
, en lugar de establecer la GIT_EXTERNAL_DIFF
variable de entorno, y funciona igualmente bien.
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`
Después de mirar algunas otras herramientas de diferencias externas, descubrí que la diff
vista en IntelliJ IDEA (y Android Studio) es la mejor para mí.
Si desea utilizar IntelliJ IDEA como su herramienta de diferencias, primero debe configurar IntelliJ IDEA para que se ejecute desde la línea de comandos siguiendo las instrucciones aquí :
En macOS o UNIX:
Tools | Create Command-line Launcher
. Se abre el cuadro de diálogo Crear secuencia de comandos de inicio, con la ruta sugerida y el nombre de la secuencia de comandos de inicio. Puede aceptar el valor predeterminado o especificar su propia ruta. Anótelo, ya que lo necesitará más tarde. Fuera de IntelliJ IDEA, agregue la ruta y el nombre de la secuencia de comandos del iniciador a su ruta.En Windows:
Siguiendo las instrucciones en esta publicación de blog :
Golpetazo
export INTELLIJ_HOME /Applications/IntelliJ\ IDEA\ CE.app/Contents/MacOS
PATH=$IDEA_HOME $PATH
Pez
set INTELLIJ_HOME /Applications/IntelliJ\ IDEA\ CE.app/Contents/MacOS
set PATH $INTELLIJ_HOME $PATH
Ahora agregue lo siguiente a su configuración 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
ogit difftool HEAD~1
esto funciona para mí en Windows 7. No hay necesidad de scripts intermedios sh
contenido de .gitconfig:
[diff]
tool = kdiff3
[difftool]
prompt = false
[difftool "kdiff3"]
path = C:/Program Files (x86)/KDiff3/kdiff3.exe
cmd = "$LOCAL" "$REMOTE"
path
y cambié cmd
a"\"C:/Program Files (x86)/KDiff3/kdiff3.exe\" \"$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 úselo escribiendo (opcionalmente, también especificando el nombre del archivo):
git difftool
Como referencia, me gustaría incluir mi variación en la respuesta de VonC. Tenga en cuenta que estoy usando la versión MSys de Git (1.6.0.2 en este momento) con la RUTA modificada, y ejecuto Git desde Powershell (o cmd.exe), no el shell Bash.
Introduje un nuevo comando, gitdiff
. Ejecutar este comando redirige temporalmente git diff
para usar un programa visual diff 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 predeterminada de Git diff ( git diff
) como la funcionalidad visual diff ( gitdiff
). Ambos comandos toman los mismos parámetros, por ejemplo, para diferenciar visualmente los cambios en un archivo en particular, puede escribir
gitdiff path/file.txt
Tenga en cuenta que $GitInstall
se utiliza como marcador de posición para el directorio donde está instalado Git.
Crea un nuevo archivo, $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
Cree un nuevo archivo $GitInstall\bin\git-diff-visual.cmd
(reemplazando el [visual_diff_exe]
marcador de posición con la ruta completa al programa diff que elija)
@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
Ya terminaste. Ejecutar gitdiff
desde un repositorio de Git ahora debería invocar su programa visual diff para cada archivo que se modificó.
Aquí hay un archivo por lotes que funciona para Windows: supone que DiffMerge está instalado en la ubicación predeterminada, maneja x64, maneja el reemplazo de barra diagonal inversa según sea necesario y tiene la capacidad de instalarse. Debería ser fácil reemplazar DiffMerge con su programa de diferencias favorito.
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á en una Mac y tiene XCode, entonces tiene instalado FileMerge. El comando de terminal es opendiff, así que solo puedes hacergit difftool -t opendiff
Instalar meld
# apt-get install meld
Luego elige eso como difftool
$ git config --global diff.tool meld
Si desea ejecutarlo en el tipo de consola:
$ git difftool
Si desea utilizar el modo de tipo gráfico:
$ 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):
Entonces, presione enter para usar meld (predeterminado), esto abriría el modo gráfico, haría que la magia se guardara y presione que resuelva la fusión. Eso es todo
Para una versión de Linux de cómo configurar una herramienta diff en versiones de git anteriores a 1.6.3 (1.6.3 agregó difftool a git), este es un gran tutorial conciso,
en breve:
Paso 1: agrega esto a tu .gitconfig
[diff]
external = git_diff_wrapper
[pager]
diff =
Paso 2: crea un archivo llamado git_diff_wrapper, ponlo en algún lugar de tu $ PATH
#!/bin/sh
vimdiff "$2" "$5"
En Mac OS X,
git difftool -t diffuse
hace el trabajo por mí en la carpeta git. Para instalar difuso, uno puede usar el puerto -
sudo port install diffuse
Lo siguiente se puede obtener de las otras respuestas aquí, pero para mí es difícil (demasiada información), así que aquí está la respuesta 'solo escríbelo' para tkdiff:
git difftool --tool=tkdiff <path to the file to be diffed>
Puede sustituir el nombre ejecutable de su herramienta de diferenciación favorita por tkdiff. Mientras (por ejemplo, tkdiff), (o su herramienta de diferenciación favorita) esté en su RUTA, se iniciará.
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
Yo uso kompare en ubuntu:
sudo apt-get install kompare
Para comparar dos ramas:
git difftool -t kompare <my_branch> master
He estado usando este bit ~/.gitconfig
durante mucho tiempo:
[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 un entorno gráfico, y no es trivial invocar el diff normal con esta configuración, 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 configuración, cosas como esta funcionan:
git v
git v --staged
git v -t kompare
git v --staged -t tkdiff
Y todavía puedo mantener lo bueno de siempre git diff
.
Si ya tiene una herramienta de diferencias asociada con los tipos de archivo (por ejemplo, porque instaló TortoiseSVN que viene con un visor de diferencias), podría simplemente canalizar la git diff
salida regular a un archivo "temporal", luego simplemente abrir ese archivo directamente sin necesidad de saber cualquier cosa 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 comando, entonces si instalas tortoise git puedes hacer clic derecho en un archivo para obtener un submenú tortoisegit con la opción "Diferenciar más tarde".
Cuando selecciona esto en el primer archivo, puede hacer clic con el botón derecho en el segundo archivo, ir al submenú tortoisegit y seleccionar "Diferenciar con == yourfilehere ==" Esto le dará a la tortoisegitmerge gui para el resultado.
Es posible que desee probar xd http://github.com/jiqingtang/xd , que es el contenedor GUI para GIT / SVN diff. NO es una herramienta diff en sí misma. Ejecutas xd
cuando quieres ejecutar git diff
o svn diff
y te mostrará una lista de archivos, una ventana de vista previa y puedes iniciar cualquier herramienta de diferencia que desees, incluyendo tkdiff, xxdiff, gvimdiff, emacs (ediff), xemacs (ediff), meld, difuso, 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.
git config diff.tool winmerge
. Verifique que funcionó escribiendogit difftool
. Deshágase de la escritura rápidagit config --global difftool.prompt false
. Recomiendo p4merge en lugar de winmerge.