如何使用我喜欢的差异工具/查看器查看“git diff”输出?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/255202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I view 'git diff' output with my preferred diff tool/ viewer?
提问by user3891
When I type git diff
, I want to view the output with my visual diff tool of choice (SourceGear "diffmerge" on Windows). How do I configure git to do this?
当我输入 时git diff
,我想使用我选择的视觉差异工具(Windows 上的 SourceGear“diffmerge”)查看输出。我如何配置 git 来做到这一点?
采纳答案by VonC
Since Git1.6.3, you can use the git difftool script: see my answer below.
从 Git1.6.3 开始,你可以使用git difftool 脚本:见下面我的回答。
May be this articlewill help you. Here are the best parts:
也许这篇文章会对你有所帮助。以下是最好的部分:
There are two different ways to specify an external diff tool.
有两种不同的方法可以指定外部差异工具。
The first is the method you used, by setting the GIT_EXTERNAL_DIFF variable. However, the variable is supposed to point to the full path of the executable. Moreover, the executable specified by GIT_EXTERNAL_DIFF will be called with a fixed set of 7 arguments:
第一个是您使用的方法,通过设置 GIT_EXTERNAL_DIFF 变量。但是,该变量应该指向可执行文件的完整路径。此外,由 GIT_EXTERNAL_DIFF 指定的可执行文件将使用一组固定的 7 个参数调用:
path old-file old-hex old-mode new-file new-hex new-mode
As most diff tools will require a different order (and only some) of the arguments, you will most likely have to specify a wrapper script instead, which in turn calls the real diff tool.
由于大多数 diff 工具将需要不同顺序(并且只有一些)的参数,因此您很可能必须指定一个包装脚本,它反过来调用真正的 diff 工具。
The second method, which I prefer, is to configure the external diff tool via "git config". Here is what I did:
我更喜欢的第二种方法是通过 "git config" 配置外部差异工具。这是我所做的:
1) Create a wrapper script "git-diff-wrapper.sh" which contains something like
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>" "" "" | cat
--8<-(snap)--
As you can see, only the second ("old-file") and fifth ("new-file") arguments will be passed to the diff tool.
如您所见,只有第二个(“旧文件”)和第五个(“新文件”)参数会传递给 diff 工具。
2) Type
2) 类型
$ git config --global diff.external <path_to_wrapper_script>
at the command prompt, replacing with the path to "git-diff-wrapper.sh", so your ~/.gitconfig contains
在命令提示符下,替换为“git-diff-wrapper.sh”的路径,因此您的 ~/.gitconfig 包含
-->8-(snip)--
[diff]
external = <path_to_wrapper_script>
--8<-(snap)--
Be sure to use the correct syntax to specify the paths to the wrapper script and diff tool, i.e. use forward slashed instead of backslashes. In my case, I have
确保使用正确的语法来指定包装脚本和差异工具的路径,即使用正斜杠而不是反斜杠。就我而言,我有
[diff]
external = \"c:/Documents and Settings/sschuber/git-diff-wrapper.sh\"
in .gitconfig and
在 .gitconfig 和
"d:/Program Files/Beyond Compare 3/BCompare.exe" "" "" | cat
in the wrapper script. Mind the trailing "cat"!
在包装脚本中。注意尾随的“猫”!
(I suppose the '| cat
' is needed only for some programs which may not return a proper or consistent return status. You might want to try without the trailing cat if your diff tool has explicit return status)
(我想| cat
只有某些程序可能不会返回正确或一致的返回状态,才需要' '。如果您的 diff 工具具有明确的返回状态,您可能想尝试不使用尾随 cat)
(Diomidis Spinellisadds in the comments:
The
cat
command is required, becausediff(1)
, by default exits with an error code if the files differ.
Git expects the external diff program to exit with an error code only if an actual error occurred, e.g. if it run out of memory.
By piping the output ofgit
tocat
the non-zero error code is masked.
More efficiently, the program could just runexit
with and argument of 0.)
该
cat
命令是必需的,因为diff(1)
如果文件不同,默认情况下会以错误代码退出。
Git 期望外部 diff 程序仅在发生实际错误时(例如,如果内存不足)以错误代码退出。
通过管道的输出git
到cat
非零的错误代码被屏蔽。
更有效的是,该程序可以仅exit
使用 0 参数运行。)
That (the article quoted above) is the theory for external tool defined through config file(not through environment variable).
In practice (still for config file definition of external tool), you can refer to:
那(上面引用的文章)是通过配置文件(而不是通过环境变量)定义的外部工具的理论。
在实践中(仍然是外部工具的配置文件定义),可以参考:
- How do I setup DiffMerge with msysgit / gitk?which illustrates the concrete settings of DiffMerge and WinMerge for MsysGit and gitk
- How can I set up an editor to work with Git on Windows?for the definition of Notepad++ as an external editor.
- 如何使用 msysgit/gitk 设置 DiffMerge?其中说明了 DiffMerge 和 WinMerge 对 MsysGit 和 gitk 的具体设置
- 如何设置编辑器以在 Windows 上使用 Git?用于将 Notepad++ 定义为外部编辑器。
回答by VonC
To complete my previous "diff.external" config answerabove:
要完成我之前的“diff.external”配置回答:
As mentioned by Jakub, Git1.6.3 introduced git difftool, originally proposed in September 2008:
正如Jakub 所说,Git1.6.3 引入了git difftool,最初于 2008 年 9 月提出:
USAGE='[--tool=tool] [--commit=ref] [--start=ref --end=ref] [--no-prompt] [file to merge]'
(See --extcmd
in the last part of this answer)
USAGE= '[--tool=tool] [--commit=ref] [--start=ref --end=ref] [--no-prompt] [file to merge]'
(参见--extcmd
本答案的最后一部分)
$LOCAL
contains the contents of the file from the starting revision and $REMOTE
contains the contents of the file in the ending revision.$BASE
contains the contents of the file in the wor
$LOCAL
包含起始修订版$REMOTE
中的文件内容并包含结束修订版中的文件内容。$BASE
包含文件中的内容
It's basically
git-mergetool
modified to operate on the git index/worktree.The usual use case for this script is when you have either staged or unstaged changes and you'd like to see the changes in a side-by-side diff viewer (e.g.
xxdiff
,tkdiff
, etc).
它基本上被
git-mergetool
修改为在 git index/worktree 上操作。通常情况下,使用这个脚本是当你要么上演或不分级的变化,你想看到的并排侧差异观众变化(如
xxdiff
,tkdiff
等)。
git difftool [<filename>*]
Another use case is when you'd like to see the same information but are comparing arbitrary commits (this is the part where the revarg parsing could be better)
另一个用例是当您希望查看相同的信息但正在比较任意提交时(这是 revarg 解析可能更好的部分)
git difftool --start=HEAD^ --end=HEAD [-- <filename>*]
The last use case is when you'd like to compare your current worktree to something other than HEAD (e.g. a tag)
最后一个用例是当您想将当前工作树与 HEAD 以外的其他内容(例如标签)进行比较时
git difftool --commit=v1.0.0 [-- <filename>*]
Note: since Git 2.5, git config diff.tool winmerge
is enough!
See "git mergetool winmerge"
注意:从 Git 2.5 开始,git config diff.tool winmerge
就够了!
参见“ git mergetool winmerge”
And since Git 1.7.11, you have the option --dir-diff
, in order to to spawn external diff tools that can compare two directory hierarchies at a time after populating two temporary directories, instead of running an instance of the external tool once per a file pair.
而且由于Git的1.7.11,你可以选择--dir-diff
,为了产卵外部差异的工具,可以填充两个临时目录,而不是运行外部工具的实例,每一个文件对一次后的一段时间比较两个目录层次。
Before Git 2.5:
在 Git 2.5 之前:
Practical case for configuring difftool
with your custom diff tool:
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
With winmerge.sh stored in a directory part of your PATH:
将 winmerge.sh 存储在 PATH 的目录部分:
#!/bin/sh
echo Launching WinMergeU.exe:
"C:/Program Files/WinMerge/WinMergeU.exe" -u -e "" "" -dl "Local" -dr "Remote"
If you have another tool (kdiff3, P4Diff, ...), create another shell script, and the appropriate difftool.myDiffTool.cmd
config directive.
Then you can easily switch tools with the diff.tool
config.
如果您有其他工具(kdiff3、P4Diff 等),请创建另一个 shell 脚本和适当的difftool.myDiffTool.cmd
配置指令。
然后,您可以使用diff.tool
配置轻松切换工具。
You have also this blog entry by Daveto add other details.
(Or this questionfor the winmergeu
options)
您还有Dave 的这篇博客条目,用于添加其他详细信息。
(或者这个问题的winmergeu
选项)
The interest with this setting is the winmerge.sh
script: you can customize it to take into account special cases.
此设置的兴趣在于winmerge.sh
脚本:您可以自定义它以考虑特殊情况。
See for instance David Marble's answer belowfor an example which deals with:
例如,请参阅下面的David Marble的回答,以获取处理以下问题的示例:
- newfiles in either origin or destination
- removedfiles in either origin or destination
- 来源或目的地中的新文件
- 已删除源或目标中的文件
As Kem Masonmentions in his answer, you can also avoid any wrapper by using the --extcmd
option:
正如Kem Mason在他的回答中提到的,您还可以通过使用--extcmd
选项来避免任何包装:
--extcmd=<command>
Specify a custom command for viewing diffs.
git-difftool
ignores the configured defaults and runs$command $LOCAL $REMOTE
when this option is specified.
指定用于查看差异的自定义命令。
git-difftool
忽略配置的默认值并$command $LOCAL $REMOTE
在指定此选项时运行。
For instance, this is how gitk
is able to run/use any diff
tool.
例如,这是如何gitk
能够运行/使用任何diff
工具。
回答by Charles Merriam
In the spirit of answering questions that are somewhat different than asked. Try this solution:
本着回答与提出的问题有些不同的问题的精神。试试这个解决方案:
$ meld my_project_using_git
Meld understands git and provides navigating around the recent changes.
Meld 了解 git 并提供有关最近更改的导航。
回答by Seba Illingworth
With new git difftool, its as simple as adding this to your .gitconfigfile:
使用新的 git difftool,就像将其添加到您的.gitconfig文件一样简单:
[diff]
tool = any-name
[difftool "any-name"]
cmd = "\"C:/path/to/my/ext/diff.exe\" \"$LOCAL\" \"$REMOTE\""
Optionally, also add:
可选地,还添加:
[difftool]
prompt = false
Also check out diffall, a simple script I wrote to extend the annoying (IMO) default diff behaviour of opening each in serial.
另请查看diffall,这是我编写的一个简单脚本,用于扩展以串行方式打开每个的烦人(IMO)默认差异行为。
Global .gitconfig on Windows is in %USERPROFILE%\.gitconfig
Windows 上的全局 .gitconfig 位于 %USERPROFILE%\.gitconfig
回答by Jakub Nar?bski
Since git version 1.6.3 there is "git difftool" which you can configure to use your favorite graphical diff tool. Currently supported out-of-the-box are kdiff3, kompare, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, diffuseand opendiff; if the tool you want to use isn't on this list, you can always use 'difftool.<tool>.cmd
' configuration option.
从 git 版本 1.6.3开始,您可以配置“ git difftool”以使用您最喜欢的图形差异工具。目前支持的开箱即用有kdiff3、kompare、tkdiff、meld、xxdiff、emerge、vimdiff、gvimdiff、ecmerge、diffuse和opendiff;如果您要使用的工具不在此列表中,您始终可以使用“ difftool.<tool>.cmd
”配置选项。
"git difftool" accepts the same options as "git diff".
“git difftool”接受与“git diff”相同的选项。
回答by Kem Mason
I have one addition to this. I like to regularly use a diff app that isn't supported as one of the default tools (e.g. kaleidoscope), via
我还有一个补充。我喜欢经常使用不支持的 diff 应用程序作为默认工具之一(例如万花筒),通过
git difftool -t
I also like to have the default diff
just be the regular command line, so setting the GIT_EXTERNAL_DIFF
variable isn't an option.
我也喜欢将默认值diff
设为常规命令行,因此设置GIT_EXTERNAL_DIFF
变量不是一个选项。
You can use an arbitrary diff
app as a one-off with this command:
您可以使用diff
以下命令一次性使用任意应用程序:
git difftool --extcmd=/usr/bin/ksdiff
It just passes the 2 files to the command you specify, so you probably don't need a wrapper either.
它只是将 2 个文件传递给您指定的命令,因此您可能也不需要包装器。
回答by David Marble
Building on VonC's answer to deal with file removals and additions, use the following commands and scripts:
基于 VonC 处理文件删除和添加的答案,使用以下命令和脚本:
> git config --global diff.tool winmerge
> git config --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\" \"$BASE\""
> git config --global difftool.prompt false
Which is the same as putting this in your global .gitconfig
:
这与将其放在您的 global 中相同.gitconfig
:
[diff]
tool = winmerge
[difftool "winmerge"]
cmd = winmerge.bat "$LOCAL" "$REMOTE" "$BASE"
[difftool]
prompt = false
Then put the following in winmerge.sh
which must be on your path:
然后将以下内容放入winmerge.sh
您的路径中:
#!/bin/sh
NULL="/dev/null"
if [ "" = "$NULL" ] ; then
echo "removed: "
elif [ "" = "$NULL" ] ; then
echo "added: "
else
echo "changed: "
"C:/Program Files (x86)/WinMerge/WinMergeU.exe" -e -ub -dl "Base" -dr "Mine" "" ""
fi
回答by Steve Hanov
Solution for Windows/msys git
Windows/msys git 解决方案
After reading the answers, I discovered a simpler way that involves changing only one file.
阅读答案后,我发现了一种更简单的方法,只需更改一个文件。
Create a batch file to invoke your diff program, with argument 2 and 5. This file must be somewhere in your path. (If you don't know where that is, put it in c:\windows). Call it, for example, "gitdiff.bat". Mine is:
@echo off REM This is gitdiff.bat "C:\Program Files\WinMerge\WinMergeU.exe" %2 %5
Set the environment variable to point to your batch file. For example:
GIT_EXTERNAL_DIFF=gitdiff.bat
. Or through powershell by typinggit config --global diff.external gitdiff.bat
.It is important to not use quotes, or specify any path information, otherwise it won't work. That's why gitdiff.bat must be in your path.
创建一个批处理文件来调用您的 diff 程序,参数为 2 和 5。该文件必须在您的路径中的某个位置。(如果你不知道它在哪里,把它放在 c:\windows 中)。例如,称之为“gitdiff.bat”。我的是:
@echo off REM This is gitdiff.bat "C:\Program Files\WinMerge\WinMergeU.exe" %2 %5
将环境变量设置为指向您的批处理文件。例如:
GIT_EXTERNAL_DIFF=gitdiff.bat
。或者通过 powershell 键入git config --global diff.external gitdiff.bat
.重要的是不要使用引号,或指定任何路径信息,否则将不起作用。这就是为什么 gitdiff.bat 必须在您的路径中。
Now when you type "git diff", it will invoke your external diff viewer.
现在,当您输入“git diff”时,它将调用您的外部差异查看器。
回答by idbrii
If you're doing this through cygwin, you may need to use cygpath:
如果您通过 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 ` `cygpath -w `
回答by David Rawson
After looking at some other external diff tools, I found that the diff
view in IntelliJ IDEA (and Android Studio) is the best one for me.
在查看了其他一些外部差异工具后,我发现diff
IntelliJ IDEA(和 Android Studio)中的视图对我来说是最好的。
Step 1 - setup IntelliJ IDEA to be run from the command line
步骤 1 - 设置 IntelliJ IDEA 从命令行运行
If you want to use IntelliJ IDEA as your diff tool you should first setup IntelliJ IDEA to be run from the command line following the instructions here:
如果您想使用 IntelliJ IDEA 作为您的差异工具,您应该首先按照此处的说明设置 IntelliJ IDEA 从命令行运行:
On macOS or UNIX:
在 macOS 或 UNIX 上:
- Make sure IntelliJ IDEA is running.
- On the main menu, choose
Tools | Create Command-line Launcher
. The dialog box Create Launcher Script opens, with the suggested path and name of the launcher script. You can accept default, or specify your own path. Make notice of it, as you'll need it later. Outside of IntelliJ IDEA, add the path and name of the launcher script to your path.
- 确保 IntelliJ IDEA 正在运行。
- 在主菜单上,选择
Tools | Create Command-line Launcher
。创建启动程序脚本对话框打开,其中包含启动程序脚本的建议路径和名称。您可以接受默认路径,也可以指定您自己的路径。请注意它,因为您稍后会需要它。在 IntelliJ IDEA 之外,将启动程序脚本的路径和名称添加到您的路径中。
On Windows:
在 Windows 上:
- Specify the location of the IntelliJ IDEA executable in the Path system environment variable. In this case, you will be able to invoke the IntelliJ IDEA executable and other IntelliJ IDEA commands from any directory.
- 在 Path 系统环境变量中指定 IntelliJ IDEA 可执行文件的位置。在这种情况下,您将能够从任何目录调用 IntelliJ IDEA 可执行文件和其他 IntelliJ IDEA 命令。
Step 2 - configure git to use IntelliJ IDEA as the difftool
第 2 步 - 配置 git 以使用 IntelliJ IDEA 作为 difftool
Following the instructions on this blog post:
按照此博客文章中的说明进行操作:
Bash
重击
export INTELLIJ_HOME /Applications/IntelliJ\ IDEA\ CE.app/Contents/MacOS
PATH=$IDEA_HOME $PATH
Fish
鱼
set INTELLIJ_HOME /Applications/IntelliJ\ IDEA\ CE.app/Contents/MacOS
set PATH $INTELLIJ_HOME $PATH
Now add the following to your git config:
现在将以下内容添加到您的 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")
You can try it out with git difftool
or git difftool HEAD~1
您可以尝试使用git difftool
或git difftool HEAD~1