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

use*_*891 735 git diff diffmerge difftool git-difftool

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

Von*_*onC 382

从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
Run Code Online (Sandbox Code Playgroud)

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

我更喜欢的第二种方法是通过"git config"配置外部diff工具.这是我做的:

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)--
Run Code Online (Sandbox Code Playgroud)

如您所见,只有第二个("old-file")和第五个("new-file")参数将传递给diff工具.

2)类型

$ git config --global diff.external <path_to_wrapper_script>
Run Code Online (Sandbox Code Playgroud)

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

-->8-(snip)--
[diff]
    external = <path_to_wrapper_script>
--8<-(snap)--
Run Code Online (Sandbox Code Playgroud)

一定要使用正确的语法来指定包装器脚本和diff工具的路径,即使用forward slashed而不是反斜杠.就我而言,我有

[diff]
    external = \"c:/Documents and Settings/sschuber/git-diff-wrapper.sh\"
Run Code Online (Sandbox Code Playgroud)

在.gitconfig和

"d:/Program Files/Beyond Compare 3/BCompare.exe" "$2" "$5" | cat
Run Code Online (Sandbox Code Playgroud)

在包装器脚本中.介意尾随"猫"!

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

(Diomidis Spinellis 在评论中补充道:

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


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

  • 荣誉......这非常方便.我用"opendiff"(在Mac OS X下启动光滑的XCode FileMerge实用程序)进行设置. (4认同)
  • 啊,我设置了外部差异程序,但不知道 7 个参数,谢谢。 (2认同)
  • 那么git将7个参数发送到diff程序?我对Git的了解越多,我就觉得它是针对一个人制作的:原始程序员。这种dvc似乎更像是个闪亮的玩具,没有太大的作用。 (2认同)

Von*_*onC 209

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

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

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

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

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

通常情况下,使用这个脚本是当你要么上演或不分级的变化,你想看到的并排侧差异观众变化(如xxdiff,tkdiff等).

git difftool [<filename>*]
Run Code Online (Sandbox Code Playgroud)

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

git difftool --start=HEAD^ --end=HEAD [-- <filename>*]
Run Code Online (Sandbox Code Playgroud)

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

git difftool --commit=v1.0.0 [-- <filename>*]
Run Code Online (Sandbox Code Playgroud)

注意:既然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
Run Code Online (Sandbox Code Playgroud)

将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"
Run Code Online (Sandbox Code Playgroud)

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

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

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

请参阅下面的David Marble答案,其中的一个例子涉及:

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

正如Kem Mason他的回答中提到的那样,你也可以通过使用--extcmd选项来避免任何包装:

--extcmd=<command>
Run Code Online (Sandbox Code Playgroud)

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

例如,这是如何gitk运行/使用任何diff工具.

  • 我不得不逃避$,$ LOCAL和$ REMOTE以防止它们成为""和"".我会编辑说git config --globla difftool.winmerge.cmd"winmerge.sh \"\ $ LOCAL \"\"\ $ REMOTE \"" (11认同)

Cha*_*iam 109

本着回答与问题有所不同的问题的精神.尝试此解决方案:

$ meld my_project_using_git
Run Code Online (Sandbox Code Playgroud)

Meld了解git并提供围绕最近变化的导航.

  • 这比输入`meld .`更好,比`git difftool`更容易,并且必须按顺序查看已更改的文件.而且它更接近Mercurial的`hg vdiff`插件. (17认同)
  • 此外,"meld."也适用于Mercurial和Subversion项目,万一有人好奇. (6认同)
  • 如果您想查看当前的更改,那就太好了。我发现 `git difftool -y -t meld --dir-diff other_branch` 也很有用,可以查看与任何分支的差异。 (2认同)

Jak*_*ski 40

从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 kdiff3 HEAD` (8认同)

Seb*_*rth 39

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

[diff]
    tool = any-name
[difftool "any-name"]
    cmd = "\"C:/path/to/my/ext/diff.exe\" \"$LOCAL\" \"$REMOTE\""
Run Code Online (Sandbox Code Playgroud)

另请参阅diffall,我编写的一个简单脚本,用于扩展烦人的(IMO)默认差异行为,打开每个串行连接.

  • +1表示不需要包装器脚本的方法 (3认同)

Kem*_*son 24

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

git difftool -t
Run Code Online (Sandbox Code Playgroud)

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

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

git difftool --extcmd=/usr/bin/ksdiff
Run Code Online (Sandbox Code Playgroud)

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

  • 好点:还没有人提到“--extcmd”选项。+1。我已将其包含在我的答案中。 (2认同)

小智 19

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

> git config --global diff.tool winmerge
> git config --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\" \"$BASE\""
> git config --global difftool.prompt false
Run Code Online (Sandbox Code Playgroud)

这与将其放入您的全局相同.gitconfig:

[diff]
    tool = winmerge
[difftool "winmerge"]
    cmd = winmerge.bat "$LOCAL" "$REMOTE" "$BASE"
[difftool]
    prompt = false
Run Code Online (Sandbox Code Playgroud)

然后把以下内容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
Run Code Online (Sandbox Code Playgroud)


Ste*_*nov 12

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
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将环境变量设置为指向批处理文件.例如:GIT_EXTERNAL_DIFF=gitdiff.bat.或者通过键入PowerShell git config --global diff.external gitdiff.bat.

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

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


idb*_*rii 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`
Run Code Online (Sandbox Code Playgroud)


Sha*_*ras 8

这对我在Windows 7上工作.不需要中间sh脚本

.gitconfig的内容:

    [diff]
      tool = kdiff3

    [difftool]
       prompt = false

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

  • 谢谢.这对我来说不太有用,但是当我删除`path`并将`cmd`更改为`"\"C:/ Program Files(x86)/KDiff3/kdiff3.exe \"\"$ LOCAL \"\"$ REMOTE \""` (2认同)

Dav*_*son 8

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

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

如果你想使用的IntelliJ IDEA作为比较工具,你应该先设置的IntelliJ IDEA从下面的说明在命令行中运行:

在macOS或UNIX上:

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

在Windows上:

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

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

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

巴什

export INTELLIJ_HOME /Applications/IntelliJ\ IDEA\ CE.app/Contents/MacOS
PATH=$IDEA_HOME $PATH
Run Code Online (Sandbox Code Playgroud)

set INTELLIJ_HOME /Applications/IntelliJ\ IDEA\ CE.app/Contents/MacOS
set PATH $INTELLIJ_HOME $PATH
Run Code Online (Sandbox Code Playgroud)

现在将以下内容添加到您的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")
Run Code Online (Sandbox Code Playgroud)

你可以尝试用git difftoolgit difftool HEAD~1


小智 7

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

git difftool --tool-help
git config --global diff.tool <chosen tool>
git config --global --add difftool.prompt false
Run Code Online (Sandbox Code Playgroud)

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

git difftool
Run Code Online (Sandbox Code Playgroud)


Mil*_*ian 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
Run Code Online (Sandbox Code Playgroud)

建立

请注意,$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
    
    Run Code Online (Sandbox Code Playgroud)
  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
    
    Run Code Online (Sandbox Code Playgroud)
  3. 你现在完成了.gitdiff从Git存储库中运行现在应该为每个已更改的文件调用visual diff程序.


Bra*_*son 6

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

安装:

gitvdiff --install 
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


Lux*_*ode 6

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

  • 使用-y选项可以避免恼人的提示.不幸的是,git将等到FileMerge退出之后再提供下一个更改的文件.使用-d选项一次性进行目录比较. (2认同)

G. *_*Joe 6

安装融合

 # apt-get install meld
Run Code Online (Sandbox Code Playgroud)

然后选择它作为difftool

 $ git config --global diff.tool meld
Run Code Online (Sandbox Code Playgroud)

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

 $ git difftool
Run Code Online (Sandbox Code Playgroud)

如果要使用图形模式类型:

 $ git mergetool
Run Code Online (Sandbox Code Playgroud)

输出将是:

 '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):
Run Code Online (Sandbox Code Playgroud)

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


Fir*_*row 5

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

简单来说:

第1步:将此添加到.gitconfig

[diff]
  external = git_diff_wrapper
[pager]
  diff =
Run Code Online (Sandbox Code Playgroud)

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

#!/bin/sh

vimdiff "$2" "$5"
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

415869 次

最近记录:

6 年,5 月 前