协慌网

登录 贡献 社区

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

当我输入git diff ,我想使用我选择的可视化 diff 工具(在 Windows 上为 SourceGear“diffmerge”)查看输出。如何配置 git 来做到这一点?

答案

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


可能本文会为您提供帮助。这是最好的部分:

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

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

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

由于大多数差异工具将需要使用不同顺序(且仅某些参数)的参数,因此您极有可能必须指定包装器脚本,从而调用真正的差异工具。

我更喜欢的第二种方法是通过 “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)--

如您所见,只有第二个(“旧文件”)和第五个(“新文件”)参数将传递给 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 '。如果您的 diff 工具具有显式的返回状态,您可能希望不使用尾随 cat 进行尝试)

Diomidis Spinellis 在评论中添加:

cat命令是必需的,因为如果文件不同,默认情况下diff(1)以错误代码退出。
Git 期望仅当发生实际错误(例如,内存不足)时,外部 diff 程序才会以错误代码退出。
通过将git的输出传递给cat ,可以屏蔽非零错误代码。
更有效的是,该程序只需使用参数 0 exit 。)


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

要完成我之前的“diff.external” 配置答案 ,请执行以下操作:

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

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

$LOCAL包含起始修订版中文件的内容, $REMOTE包含终止修订版中文件的内容。
$BASE包含该文件的内容

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

此脚本的通常用例是当您已暂存或未暂存更改,并且希望在并排的 diff 查看器(例如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 --dir-diff ,您可以使用--dir-diff选项,以便在填充两个临时目录后生成可以同时比较两个目录层次结构的外部 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 等),请创建另一个外壳程序脚本和相应的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,并提供了有关最新更改的导航。