如何使用首选的差异工具/查看器查看'git diff'输出?



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

从 Git1.6.3 开始,你可以使用 git difftool 脚本:请参阅下面的答案。


也许这篇文章会对你有所帮助。以下是最好的部分:

有两种

不同的方法可以指定外部比较工具。

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

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

由于大多数差异工具需要不同的参数顺序(并且只有部分(,因此您很可能必须指定一个包装脚本,该脚本又调用真正的差异工具。

我更喜欢的第二种方法是通过"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]
    external = "c:/Documents and Settings/sschuber/git-diff-wrapper.sh"

在 .gitconfig 和

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

在包装脚本中。注意尾随的"猫"!

(我想"| cat"仅适用于某些可能无法返回正确或一致的返回状态的程序。如果您的 diff 工具具有明确的返回状态,您可能想尝试不使用尾随猫(

(Diomidis Spinellis在评论中补充说:

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


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

  • 如何使用 msysgit/gitk 设置 DiffMerge?这说明了 DiffMerge 和 WinMerge for MsysGit 和 gitk 的具体设置
  • 如何设置编辑器以在 Windows 上使用 Git?,以将 Notepad++ 定义为外部编辑器。

要完成我之前的"diff.external"配置答案:

正如 Jakub 所提到的,Git1.6.3 引入了最初在 2008 年 9 月提出的 git difftool

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

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

它基本上git-mergetool修改为在 git 索引/工作树上运行。

此脚本的常见用例是,当您有暂存或未暂存的更改,并且您希望在并排差异查看器中查看更改时(例如 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">

从 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配置轻松切换工具。

您还有Dave的博客条目,以添加其他详细信息.
(或者这个问题winmergeu选项(

此设置的重点是winmerge.sh脚本:您可以自定义它以考虑特殊情况。

例如,请参阅下面的David Marble的答案,以获取有关以下内容的示例:

  • 源或目标中的文件
  • 已删除源或目标中的文件
<小时 />

正如 Kem Mason 在他的回答中提到的,您还可以通过使用 --extcmd 选项来避免任何包装器

--extcmd=<command>

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

例如,这就是gitk能够运行/使用任何diff工具的方式。

试试这个解决方案:

$ meld my_project_using_git

Meld 了解 Git 并提供围绕最近更改的导航。

使用新的 git difftool,只需将其添加到 .gitconfig 文件中即可:

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

(可选(还可以添加:

[difftool]
    prompt = false

另请查看 diffall,这是我编写的一个简单的脚本,用于扩展以串行方式打开每个的烦人 (IMO( 默认差异行为。

Windows 上的全局 .gitconfig 已%USERPROFILE%.gitconfig

从 Git 版本 1.6.3 开始,有">git difftool",您可以将其配置为使用您喜欢的图形差异工具。

目前支持的(在撰写本答案时(开箱即用的是KDiff3,Kompare,tkdiff,Meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,Diffuseopendiff;如果您要使用的工具不在此列表中,您可以随时使用" difftool.<tool>.cmd"配置选项。

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

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

git difftool -t

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

您可以使用以下命令将任意diff应用程序用作一次性应用:

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

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

基于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

Windows/MSYS Git的解决方案

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

  1. 创建一个批处理文件以调用您的 diff 程序,参数为 2 和 5。此文件必须位于路径中的某个位置。(如果你不知道它在哪里,把它放在C:\windows中。例如,称它为"gitdiff.bat"。我的是:

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

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

现在,当您键入"git diff"时,它将调用您的外部差异查看器。

如果你通过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`

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

步骤 1 - 将 IntelliJ IDEA 设置为从命令行运行

如果你想使用IntelliJ IDEA作为你的比较工具,你应该首先设置IntelliJ IDEA按照这里的说明从命令行运行:

在 macOS 或 UNIX 上:

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

在视窗上:

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

步骤 2 - 配置 git 以使用 IntelliJ IDEA 作为 difftool

按照此博客文章中的说明进行操作:

砰��

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尝试一下

之前精彩答案的简短总结:

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

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

git difftool

这在Windows 7上对我有用。不需要中间 sh 脚本

.gitconfig 的内容:

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

安装 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):

因此,只需按回车键即可使用融合(默认(。这将打开图形模式。进行魔术保存,然后按解决合并的按钮。就这样。

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

要安装:

gitvdiff --install 

吉特维.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)%SourceGearDiffMergeDiffMerge.exe"
) else (
    Set DIFF="%ProgramFiles%SourceGearDiffMergeDiffMerge.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

如果您使用的是 Mac 并且安装了 Xcode,则已安装 FileMerge。终端命令是 opendiff,所以你可以只做:

git difftool -t opendiff

简介

作为参考,我想包括我对 VonC 答案的变体。请记住,我使用的是 MSys 版本的 Git(目前为 1.6.0.2(和修改后的 PATH,并从 PowerShell(或 cmd.exe(运行 Git 本身,而不是 Bash shell。

我引入了一个新命令,gitdiff.运行此命令会暂时重定向git diff以使用您选择的可视化差异程序(而不是永久执行此操作的 VonC 解决方案(。这允许我同时拥有默认的 Git 差异功能(git diff(和视觉差异功能(gitdiff(。这两个命令采用相同的参数,因此例如,要直观地比较特定文件中的更改,您可以键入

gitdiff path/file.txt

设置

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

  1. 创建新文件,$GitInstallcmdgitdiff.cmd

     @echo off
     setlocal
     for /F "delims=" %%I in ("%~dp0..") do @set path=%%~fIbin;%%~fImingwbin;%PATH%
     if "%HOME%"=="" @set HOME=%USERPROFILE%
     set GIT_EXTERNAL_DIFF=git-diff-visual.cmd
     set GIT_PAGER=cat
     git diff %*
     endlocal
    
  2. 创建一个新文件,$GitInstallbingit-diff-visual.cmd(将占位符替换为您选择的 diff 程序的完整路径[visual_diff_exe](

     @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现在应该为每个更改的文件调用视觉差异程序。

对于如何在 1.6.3 之前的 Git 版本上配置差异工具的 Linux 版本(1.6.3 为 Git 添加了 difftool(,这是一个非常简洁的教程。

简述:

第 1 步:将其添加到您的 .gitconfig

[diff]
  external = git_diff_wrapper
[pager]
  diff =

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

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

在 Mac OS X 上,

git difftool -t diffuse

在 Git 文件夹中为我完成工作。要安装 Diffuse,可以使用端口 -

sudo port install diffuse

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

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

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

您可以使用git difftool .

例如,如果您有 Meld,则可以通过以下方式编辑分支masterdevel

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

我在这里尝试了花哨的东西(使用 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

我已经在文件~/.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.

我在 Ubuntu 上使用 Kompare:

sudo apt-get install kompare

要比较两个分支,请执行以下操作:

git difftool -t kompare <my_branch> master

如果您碰巧已经有一个与文件类型关联的差异工具(例如,因为您安装了带有差异查看器的 TortoiseSVN(,您只需将常规git diff输出通过管道传输到"临时"文件,然后直接打开该文件而无需了解有关查看器的任何信息:

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

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

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

如果您不是命令行的人,那么如果您安装 TortoiseGit,您可以右键单击一个文件以获取带有"稍后比较"选项的 TortoiseGit 子菜单。

当您在第一个文件上选择此选项时,您可以右键单击第二个文件,转到 TortoiseGit 子菜单并选择"与 ==yourfilehere== 的比较"。这将为结果提供 TortoiseGit 合并 GUI。

你可能想试试xd,这是一个用于Git/SVN差异的GUI包装器。它本身是一个差异工具。

当您想要运行git diffsvn diff时,您可以运行xd,它会显示文件列表,预览窗口,您可以启动任何您喜欢的差异工具,包括tkdiff,xxdiff,gvimdiff,Emacs(ediff(,XEmacs(ediff(,Meld,Diffuse,Kompare和KDiff3。您还可以运行任何自定义工具。

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

披露:我是这个工具的作者。

相关内容

  • 没有找到相关文章

最新更新