如何使用我喜欢的diff工具/查看器查看'git diff'输出?

时间:2008-10-31 22:55:12

标签: git diff difftool git-difftool diffmerge

当我输入git diff时,我想用我选择的视觉差异工具(Windows上的SourceGear“diffmerge”)查看输出。如何配置git来执行此操作?

26 个答案:

答案 0 :(得分:375)

自Git1.6.3起,您可以使用 git difftool脚本:请参阅my answer below


可能是这个article会帮助你。这是最好的部分:

指定外部差异工具有两种不同的方法。

第一个是您使用的方法,通过设置GIT_EXTERNAL_DIFF变量。但是,该变量应该指向可执行文件的完整路径。此外,GIT_EXTERNAL_DIFF指定的可执行文件将使用一组固定的7个参数调用:

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

由于大多数diff工具需要不同的顺序(并且只有一些),你很可能不得不指定一个包装脚本,而后者又会调用真正的diff工具。

我更喜欢的第二种方法是通过“git”配置外部差异工具 配置“。这是我做的:

1)创建一个包装脚本“git-diff-wrapper.sh”,其中包含类似

的内容
-->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)--

如您所见,只有第二个(“旧文件”)和第五个(“新文件”)参数将是 传递给差异工具。

2)输入

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

在命令提示符下,替换为“git-diff-wrapper.sh”的路径,所以你的〜/ .gitconfig包含

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

确保使用正确的语法指定包装器脚本和diff的路径 工具,即使用向前削减而不是反斜杠。就我而言,我有

[diff]
    external = \"c:/Documents and Settings/sschuber/git-diff-wrapper.sh\"
<。>在.gitconfig和

"d:/Program Files/Beyond Compare 3/BCompare.exe" "$2" "$5" | cat
包装器脚本中的

。记住尾随的“猫”!

(我想只有某些程序可能无法返回正确或一致的返回状态才需要'| cat'。如果你的diff工具有明确的返回状态,你可能想尝试没有尾随的猫)< / p>

Diomidis Spinellis添加in the comments

  

cat命令是必需的,因为如果文件不同,diff(1)默认情况下会退出并显示错误代码。
  Git希望外部差异程序仅在发生实际错误时以错误代码退出,例如如果内存不足。
  通过将git的输出汇总到cat,可以屏蔽非零错误代码   更有效的是,程序可以运行exit和参数为0。)


那(上面引用的文章)是通过配置文件定义的外部工具的理论(不是通过环境变量)。
在实践中(仍然用于外部工具的配置文件定义),您可以参考:

答案 1 :(得分:204)

完成我之前的"diff.external" config answer

作为mentioned by Jakub,Git1.6.3引入了git difftool,最初于2008年9月提出:

USAGE = '[--tool=tool] [--commit=ref] [--start=ref --end=ref] [--no-prompt] [file to merge]'
(请参阅本答案最后部分的--extcmd

$LOCAL包含起始版本中文件的内容,$REMOTE包含结束版本中文件的内容。
$BASE包含文件

中文件的内容
  

基本上git-mergetool修改了git index / worktree。

     

此脚本的通常用例是,当您有分阶段或未分阶段的更改并且您希望在并排差异查看器中看到更改时(例如xxdifftkdiff等等。)

git difftool [<filename>*]
  

另一个用例是当你想看到相同的信息但是正在比较任意提交时(这是revarg解析可能更好的部分)

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

最后一个用例是当您想要将当前的工作树与HEAD以外的其他工具(例如标签)进行比较时

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

注意:从Git 2.5开始,git config diff.tool winmerge就够了!
请参阅“git mergetool winmerge

since Git 1.7.11,您可以选择--dir-diff,以便生成外部差异工具,可以在填充两个临时目录后一次比较两个目录层次结构,而不是运行实例每个文件对一次外部工具。


在Git 2.5之前:

使用自定义差异工具配置difftool的实际案例:

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

将winmerge.sh存储在PATH的目录部分中:

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

如果您有其他工具(kdiff3,P4Diff,...),请创建另一个shell脚本和相应的difftool.myDiffTool.cmd配置指令。
然后,您可以使用diff.tool配置轻松切换工具。

您还可以使用此blog entry by Dave添加其他详细信息 (或winmergeu选项的this question

此设置的兴趣是 winmerge.sh脚本:您可以对其进行自定义以考虑特殊情况。

例如,请参阅David Marbleanswer below以获取处理以下内容的示例:

  • 原始或目的地的文件
  • 删除了
  • 中的文件

Kem Mason中提及his answer时,您还可以使用--extcmd选项来避免任何包装:

--extcmd=<command>
  

指定用于查看差异的自定义命令。 git-difftool会忽略配置的默认值,并在指定此选项时运行 $command $LOCAL $REMOTE

例如,这就是gitk is able to run/use any diff tool

的方式

答案 2 :(得分:108)

本着回答有些不同于问题的问题的精神。试试这个解决方案:

$ meld my_project_using_git

Meld了解git并提供最近的变化。

答案 3 :(得分:40)

从git 1.6.3开始,有“ git difftool ”,您可以将其配置为使用自己喜欢的图形差异工具。目前支持的开箱即用的是 kdiff3,kompare,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,diffuse opendiff ;如果您要使用的工具不在此列表中,则可以始终使用“difftool.<tool>.cmd”配置选项。

“git difftool”接受与“git diff”相同的选项。

答案 4 :(得分:36)

使用新的git difftool ,就像将其添加到 .gitconfig 文件一样简单:

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

Also check out diffall,我编写的一个简单脚本,用于扩展恼人的(IMO)默认差异行为,即打开每个串行链接。

答案 5 :(得分:23)

我还有一个补充。我喜欢经常使用不支持作为默认工具之一的差异应用程序(例如万花筒),通过

git difftool -t

我也希望默认diff只是常规命令行,因此设置GIT_EXTERNAL_DIFF变量不是一种选择。

您可以使用此命令将任意diff应用作为一次性使用:

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

它只是将2个文件传递给您指定的命令,因此您可能也不需要包装器。

答案 6 :(得分:17)

在VonC处理文件删除和添加的答案的基础上,使用以下命令和脚本:

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

将其放入您的全球.gitconfig

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

然后将以下内容放在winmerge.sh中,这必须在您的路径上:

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

答案 7 :(得分:11)

Windows / msys git的解决方案

在阅读答案后,我发现了一种更简单的方法,只涉及更改一个文件。

  1. 使用参数2和5创建批处理文件以调用diff程序。此文件必须位于路径中的某个位置。 (如果您不知道它在哪里,请将其放在c:\ windows中)。称之为“gitdiff.bat”。我的是:

    @echo off
    REM This is gitdiff.bat
    "C:\Program Files\WinMerge\WinMergeU.exe" %2 %5
    
  2. 将环境变量设置为指向批处理文件。例如:GIT_EXTERNAL_DIFF=gitdiff.bat。或者通过键入git config --global diff.external gitdiff.bat

    通过powershell

    重要的是不要使用引号,或指定任何路径信息,否则它将无法工作。这就是为什么gitdiff.bat必须在你的道路上。

  3. 现在当你输入“git diff”时,它会调用你的外部差异查看器。

答案 8 :(得分:9)

如果您是通过cygwin执行此操作,则可能需要使用 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`

答案 9 :(得分:8)

在查看其他一些外部差异工具后,我发现IntelliJ IDEA(和Android Studio)中的diff视图对我来说是最好的。

步骤1 - 设置要从命令行运行的IntelliJ IDEA

如果要使用IntelliJ IDEA作为diff工具,首先应按照here的说明从命令行设置IntelliJ IDEA:

在macOS或UNIX上:

  1. 确保IntelliJ IDEA正在运行。
  2. 在主菜单上,选择Tools | Create Command-line Launcher。将打开“创建启动器脚本”对话框,其中包含启动器脚本的建议路径和名称。您可以接受默认路径,也可以指定自己的路径。 请注意它,因为您以后需要它。 在IntelliJ IDEA之外,将启动器脚本的路径和名称添加到路径中。
  3. 在Windows上:

    1. 在Path系统环境变量中指定IntelliJ IDEA可执行文件的位置。在这种情况下,您将能够从任何目录调用IntelliJ IDEA可执行文件和其他IntelliJ IDEA命令。
    2. 第2步 - 配置git以使用IntelliJ IDEA作为difftool

      按照this blog post上的说明操作:

      <强>击

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

      <强>鱼

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

      现在将以下内容添加到您的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")
      

      您可以使用git difftoolgit difftool HEAD~1

      进行试用

答案 10 :(得分:7)

上述精彩答案的简短摘要:

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

然后通过键入(也可以选择指定文件名)来使用它:

git difftool

答案 11 :(得分:7)

这适用于Windows 7.无需中介sh脚本

<。pgconfig的内容:

    [diff]
      tool = kdiff3

    [difftool]
       prompt = false

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

答案 12 :(得分:6)

简介

作为参考,我想在VonC的答案中加入我的变体。请记住,我使用的是MSys版本的Git(此时为1.6.0.2),修改了PATH,并从Powershell(或cmd.exe)运行Git,而不是Bash shell。

我介绍了一个新命令gitdiff。运行此命令会暂时重定向git diff以使用您选择的可视差异程序(而不是VonC永久执行此操作的解决方案)。这允许我同时具有默认的Git diff功能(git diff)以及可视差异功能(gitdiff)。两个命令都采用相同的参数,因此例如,可以在视觉上区分特定文件中的更改,您可以键入

gitdiff path/file.txt

设置

请注意,$GitInstall用作安装Git的目录的占位符。

  1. 创建新文件$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. 创建一个新文件$GitInstall\bin\git-diff-visual.cmd(将[visual_diff_exe]占位符替换为您选择的diff程序的完整路径)

    @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. 你现在已经完成了。从Git存储库中运行gitdiff现在应该为每个已更改的文件调用visual diff程序。

答案 13 :(得分:6)

如果您使用的是Mac并拥有XCode,那么您已安装了FileMerge。终端命令是opendiff,所以你可以git difftool -t opendiff

答案 14 :(得分:6)

这是一个适用于Windows的批处理文件 - 假设DiffMerge安装在默认位置,处理x64,根据需要处理转发到反斜杠的替换,并且能够自行安装。应该很容易用您喜欢的差异程序替换DiffMerge。

安装:

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

答案 15 :(得分:5)

对于如何在1.6.3之前的git版本上配置diff工具的linux版本(1.6.3将difftool添加到git)this是一个非常简洁的教程,

简要说明:

第1步:将其添加到.gitconfig

[diff]
  external = git_diff_wrapper
[pager]
  diff =

第2步:创建一个名为git_diff_wrapper的文件,将其放在$ PATH中的某个位置

#!/bin/sh

vimdiff "$2" "$5"

答案 16 :(得分:5)

安装meld

 # apt-get install meld

然后选择它作为difftool

 $ git config --global diff.tool meld

如果想要在控制台类型上运行它:

 $ git difftool

如果您想使用图形模式类型:

 $ git mergetool

输出结果为:

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

所以只需按Enter键即可使用meld(默认),这将打开图形模式,进行魔术保存并按下即可解决合并。这就是全部

答案 17 :(得分:4)

在Mac OS X上,

git difftool -t diffuse 

在git文件夹中为我完成这项工作。要安装漫反射,可以使用端口 -

sudo port install diffuse

答案 18 :(得分:3)

您可以使用git difftool

例如,如果您有meld,则可以通过以下方式修改分支masterdevel

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

答案 19 :(得分:2)

我在这里尝试过这些花哨的东西(用tkdiff),没有什么对我有用。所以我写了下面的脚本tkgitdiff。它做我需要它做的事。

$ 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

答案 20 :(得分:2)

可以从这里的其他答案中收集以下内容,但是对我来说,这很困难,(信息太多),所以这是tkdiff的“仅输入内容”答案:

git difftool --tool=tkdiff <path to the file to be diffed>

您可以将您喜欢的差异工具的可执行文件名称替换为tkdiff。只要(例如tkdiff),(或您喜欢的比较工具)位于PATH中,它就会启动。

答案 21 :(得分:1)

我一直在~/.gitconfig中使用这个位很长一段时间:

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

使用git-meld

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

但现在我厌倦了总是在图形环境中使用meld, 使用此设置调用普通差异并非易事,所以我切换到了:

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

通过这种设置,这样的工作:

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

我仍然可以保持良好的旧git diff

答案 22 :(得分:0)

你可能想试用xd http://github.com/jiqingtang/xd,它是GIT / SVN diff的GUI包装器。它本身不是一个差异工具。当您想要运行xdgit diff时,您会运行svn diff,它会显示一个文件列表,一个预览窗口,您可以启动任何您喜欢的差异工具,包括tkdiff,xxdiff ,gvimdiff,emacs(ediff),xemacs(ediff),meld,diffuse,kompare和kdiff3。您还可以运行任何自定义工具。

不幸的是,该工具不支持Windows。

披露:我是此工具的作者。

答案 23 :(得分:0)

我在ubuntu上使用kompare:

sudo apt-get install kompare

比较两个分支:

git difftool -t kompare <my_branch> master

答案 24 :(得分:0)

如果你碰巧已经有一个与文件类型相关的差异工具(比如,因为你安装了差异查看器附带的TortoiseSVN),你可以将常规git diff输出管道传输到“临时”文件,然后只需直接打开该文件,无需了解有关查看器的任何信息:

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

将其设置为全局别名的效果更好:git what

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

答案 25 :(得分:0)

如果您不是命令行的那个,那么如果您安装了tortoise git,您可以右键单击文件以获得带有“Diff later”选项的tortoisegit子菜单。

当您在第一个文件上选择此项时,您可以右键单击第二个文件,转到tortoisegit子菜单并选择“Diff with == yourfilehere ==” 这将为结果提供tortoisegitmerge gui。