当我键入 git diff
时,我想使用我选择的可视差异工具(Windows 上的 SourceGear “diffmerge”)查看输出。我如何配置 git 来做到这一点?
git config diff.tool winmerge
。通过键入 git difftool
验证它是否有效。摆脱输入 git config --global difftool.prompt false
的提示。我推荐 p4merge 而不是 winmerge。
从 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 config”配置外部差异工具。这是我所做的:
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)--
如您所见,只有第二个(“旧文件”)和第五个(“新文件”)参数将传递给 diff 工具。
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
”仅适用于某些可能无法返回正确或一致返回状态的程序。如果您的差异工具具有明确的返回状态,您可能想尝试不使用尾随猫)
(Diomidis Spinellis 添加 in the comments:
cat 命令是必需的,因为 diff(1) 如果文件不同,默认情况下会以错误代码退出。 Git 期望外部 diff 程序仅在发生实际错误时以错误代码退出,例如内存不足。通过管道将 git 的输出传递到 cat 非零错误代码被屏蔽。更有效的是,程序可以只运行 exit 并且参数为 0。)
那(上面引用的文章)是通过配置文件(而不是通过环境变量)定义的外部工具的理论。在实践中(仍然是外部工具的配置文件定义),您可以参考:
如何使用 msysgit / gitk 设置 DiffMerge?它说明了 MsysGit 和 gitk 的 DiffMerge 和 WinMerge 的具体设置
如何设置编辑器以在 Windows 上使用 Git?用于将 Notepad++ 定义为外部编辑器。
完成我之前的"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 上运行。此脚本的通常用例是当您有暂存或未暂存的更改并且您希望在并排差异查看器中查看更改(例如 xxdiff、tkdiff 等)。
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 添加其他详细信息。
(或 this question 用于 winmergeu
选项)
此设置的有趣之处在于 winmerge.sh
脚本:您可以对其进行自定义以考虑特殊情况。
例如,请参阅 David Marble 的 answer below,了解处理以下问题的示例:
源或目标中的新文件
删除源或目标中的文件
正如 his answer 中的 Kem Mason 所述,您还可以使用 --extcmd
选项避免任何包装器:
--extcmd=<command>
指定用于查看差异的自定义命令。 git-difftool 忽略配置的默认值并在指定此选项时运行 $command $LOCAL $REMOTE。
例如,这就是 gitk
is able to run/use any diff
tool。
--start=
和 --end=
选项在 v1.7.11 中无法识别
试试这个解决方案:
$ meld my_project_using_git
Meld 了解 Git 并提供围绕最近更改的导航。
meld .
比输入 git difftool
容易得多,并且必须按顺序查看更改的文件。而且它更接近 Mercurial 的 hg vdiff
插件。
meld .
也适用于 Mercurial 和 Subversion 项目。
git difftool -y -t meld --dir-diff other_branch
也很有用,可以查看与任何分支的区别。
使用新的 git difftool,只需将其添加到 .gitconfig 文件中即可:
[diff]
tool = any-name
[difftool "any-name"]
cmd = "\"C:/path/to/my/ext/diff.exe\" \"$LOCAL\" \"$REMOTE\""
(可选)还添加:
[difftool]
prompt = false
Also check out diffall,我编写的一个简单脚本,用于扩展令人讨厌的 (IMO) 默认差异行为,即以串行方式打开每个。
Windows 上的全局 .gitconfig 位于 %USERPROFILE%\.gitconfig
从 Git 版本 1.6.3 开始,您可以配置“git difftool”以使用您最喜欢的图形差异工具。
当前支持(在撰写此答案时)开箱即用的是 KDiff3、Kompare、tkdiff、Meld、xxdiff、emerge、vimdiff、gvimdiff、ecmerge、 Diffuse 和 opendiff;如果您要使用的工具不在此列表中,您可以随时使用“difftool.<tool>.cmd
”配置选项。
“git difftool”接受与“git diff”相同的选项。
git difftool -t kdiff3 HEAD
我对此有一个补充。我喜欢定期使用不支持作为默认工具之一的差异应用程序(例如万花筒),通过
git difftool -t
我也喜欢让默认的 diff
成为常规命令行,所以设置 GIT_EXTERNAL_DIFF
变量不是一个选项。
您可以通过以下命令一次性使用任意 diff
应用程序:
git difftool --extcmd=/usr/bin/ksdiff
它只是将 2 个文件传递给您指定的命令,因此您可能也不需要包装器。
--extcmd
选项。 +1。我已将其包含在我的答案中。
在 VonC's answer 的基础上处理文件删除和添加,使用以下命令和脚本:
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
winmerge.sh
脚本的出色补充。 +1。我已更新 my answer 以链接到您的。
winmerge.bat
应该是 winmerge.sh
Windows/MSYS Git 解决方案
阅读答案后,我发现了一种更简单的方法,即只更改一个文件。
使用参数 2 和 5 创建一个批处理文件来调用您的 diff 程序。该文件必须在您的路径中的某个位置。 (如果您不知道它在哪里,请将其放在 C:\windows 中。)例如,将其命名为“gitdiff.bat”。我的是:@echo off REM 这是 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 必须在你的路径中。
现在,当您键入“git diff”时,它将调用您的外部差异查看器。
git config --global diff.external winmerge.cmd
,而不是设置 GIT_EXTERNAL_DIFF
环境变量,并且它效果同样好。
在查看了其他一些外部差异工具后,我发现 IntelliJ IDEA(和 Android Studio)中的 diff
视图对我来说是最好的。
第 1 步 - 设置 IntelliJ IDEA 以从命令行运行
如果您想使用 IntelliJ IDEA 作为您的 diff 工具,您应该首先按照说明 here 设置 IntelliJ IDEA 以从命令行运行:
在 macOS 或 UNIX 上:
确保 IntelliJ IDEA 正在运行。在主菜单上,选择工具 |创建命令行启动器。创建启动器脚本对话框打开,其中包含启动器脚本的建议路径和名称。您可以接受默认值,也可以指定自己的路径。请注意它,因为稍后您将需要它。在 IntelliJ IDEA 之外,将启动器脚本的路径和名称添加到您的路径中。
在 Windows 上:
在 Path 系统环境变量中指定 IntelliJ IDEA 可执行文件的位置。在这种情况下,您将能够从任何目录调用 IntelliJ IDEA 可执行文件和其他 IntelliJ IDEA 命令。
第 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 difftool
或 git difftool HEAD~1
进行尝试
如果您通过 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`
这适用于 Windows 7。不需要任何中间 sh 脚本
.gitconfig 的内容:
[diff]
tool = kdiff3
[difftool]
prompt = false
[difftool "kdiff3"]
path = C:/Program Files (x86)/KDiff3/kdiff3.exe
cmd = "$LOCAL" "$REMOTE"
path
并将 cmd
更改为 "\"C:/Program Files (x86)/KDiff3/kdiff3.exe\" \"$LOCAL\" \"$REMOTE\""
时它确实有效
对以前的好答案的简短总结:
git difftool --tool-help
git config --global diff.tool <chosen tool>
git config --global --add difftool.prompt false
然后通过键入(也可以指定文件名)来使用它:
git difftool
这是一个适用于 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
安装 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 即可使用融合(默认)。这将打开图形模式。进行魔法保存并按下解决合并的按钮。就这样。
介绍
作为参考,我想在 VonC's answer 中加入我的变体。请记住,我使用的是 MSys 版本的 Git(此时为 1.6.0.2)和修改过的 PATH,并从 PowerShell(或 cmd.exe)而不是 Bash shell 运行 Git 本身。
我引入了一个新命令 gitdiff
。运行此命令会暂时重定向 git diff
以使用您选择的可视差异程序(与 VonC 的永久执行此操作的解决方案相反)。这使我可以同时拥有默认的 Git 差异功能 (git diff
) 和视觉差异功能 (gitdiff
)。两个命令都采用相同的参数,例如,为了直观地区分特定文件中的更改,您可以键入
gitdiff path/file.txt
设置
请注意,$GitInstall
用作安装 Git 的目录的占位符。
创建一个新文件 $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 创建一个新的文件,$GitInstall\bin\git-diff-visual.cmd(用您选择的 diff 程序的完整路径替换 [visual_diff_exe] 占位符)@echo off rem diff 由 git 调用,带有 7 个参数:rem path old-file old -hex old-mode new-file new-hex new-mode echo Diffing "%5" "[visual_diff_exe]" "%2" "%5" exit 0 你现在完成了。从 Git 存储库中运行 gitdiff 现在应该为每个更改的文件调用您的可视差异程序。
对于如何在 1.6.3 之前的 Git 版本上配置差异工具的 Linux 版本(1.6.3 将差异工具添加到 Git),this 是一个很棒的简明教程。
简单来说:
第 1 步:将其添加到您的 .gitconfig
[diff]
external = git_diff_wrapper
[pager]
diff =
第 2 步:创建一个名为 git_diff_wrapper 的文件,将其放在 $PATH 中的某个位置
#!/bin/sh
vimdiff "$2" "$5"
以下可以从这里的其他答案中收集到,但对我来说这很困难(信息太多),所以这里是 tkdiff 的“只需输入”答案:
git difftool --tool=tkdiff <path to the file to be diffed>
你可以用你最喜欢的 diffing 工具的可执行文件名替换 tkdiff。只要(例如 tkdiff),(或您最喜欢的差异工具)在您的 PATH 中,它就会被启动。
您可以使用 git difftool
。
例如,如果您有 Meld,则可以通过以下方式编辑分支 master
和 devel
:
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 子菜单并选择“Diff with ==yourfilehere==”。这将为结果提供 TortoiseGit 合并 GUI。