默认的git差异比较工具(和合并工具)是什么?

7
默认的git diff工具(和合并工具)是什么?我应该在哪里(以及如何)找到它?
我从未明确设置过git difftool(也没有mergetool)的任何配置,因此 git config --get difftool 什么都不显示。
git文档(https://git-scm.com/docs/git-difftool)中说:
如果未设置配置变量diff.tool,则git difftool会选择一个合适的默认值。
我该如何找出它选择了哪个工具?'合适'算法是如何工作的?
让我分享一下我为什么要查找当前由我的git选择的diff工具的原因:
当我执行git diff时,遇到了一些奇怪的差异结果(我怀疑是BOM处理问题)。
我想向供应商(例如p4merge)提出疑问,
但不确定是p4mergevimdiff还是其他任何东西。
我希望可能有一个命令像git difftool --current

尝试执行命令 git difftool --tool-help - Schwern
@Schwern,--tool-help 只显示所有可能的 _候选项_,而不是当前的。 - ALittleDiff
实际上并没有特定的默认设置。Git不附带这些工具,但知道某些工具,因此如果您安装了一堆适合的工具(Git知道的),Git将选择其中一个。如果您只有一种合适的工具,Git将选择它。如果您有一种合适的工具,但Git不知道它,您需要使用设置来告诉Git。 - torek
p4merge 是如何参与其中的? - Schwern
也许更好的做法是,您提出一个关于实际问题的问题,而不是您认为导致问题的原因。在此处链接它,我会看一下。 - Schwern
2个回答

6

git difftool命令会告诉你它将要尝试做什么。

$ git difftool

This message is displayed because 'diff.tool' is not configured.
See 'git difftool --tool-help' or 'git help config' for more details.
'git difftool' will now attempt to use one of the following tools:
kompare emerge vimdiff

Viewing (1/1): 'this'
Launch 'emerge' [Y/n]?

我们可以在guess_merge_tool函数中找到该过程。
guess_merge_tool () {
    list_merge_tool_candidates
    cat >&2 <<-EOF
    This message is displayed because '$TOOL_MODE.tool' is not configured.
    See 'git ${TOOL_MODE}tool --tool-help' or 'git help config' for more details.
    'git ${TOOL_MODE}tool' will now attempt to use one of the following tools:
    $tools
    EOF

    # Loop over each candidate and stop when a valid merge tool is found.
    IFS=' '
    for tool in $tools
    do
        is_available "$tool" && echo "$tool" && return 0
    done

list_merge_tool_candidates 函数设置了 $tools 列表。它假设如果未设置 DISPLAY,就没有 GUI,但这在 MacOS 上是不正确的。

然后它简单地循环遍历这些工具,并使用type命令选择找到的第一个可执行文件。


更新

我执行git diff时遇到了一些奇怪的差异结果(我怀疑是BOM处理问题)。我想向供应商(例如p4merge)询问, 但不确定是否是p4merge、vimdiff或其他原因。

如果您遇到的是与 git diff 相关的问题,则不是 git difftool 的问题。我认为有一些关于 git difftool 功能的混淆, 所以这里简要介绍一下。

git diff 不使用 git-difftoolgit difftool 不会选择用于 git diff 的差异工具。 git diff 有自己的内部差异实现。它也可以使用外部差异程序(例如 GNU diff),只需提供 --ext-diff

当您运行 git difftool 时,它会选择一个外部差异程序,并使用三个环境变量:$LOCAL、$REMOTE 和 $MERGED。$LOCAL 是文件旧版本的路径, $REMOTE 是文件新版本的路径,$MERGED 是文件名,以便进行显示。大体如此。它与 git diff 没有关系。

我们可以通过将自定义差异工具添加到 .gitconfig 中来查看 git difftool 的操作:

[difftool "echo"]
    cmd = echo "LOCAL: $LOCAL, REMOTE: $REMOTE, MERGED: $MERGED"

[difftool "less"]
    cmd = less "$LOCAL" "$REMOTE"

git difftool -t echo将显示环境变量。git difftool -t less将在less翻页器中查看旧版本和新版本文件的内容。


如果您在使用git diff时遇到问题,git difftool、p4merge和vimdiff都与之无关。


好的,我明白在git中没有默认的diff工具这一事实,并且也理解了guess_merge_tool()算法。 但是仍然有一些问题:
  1. 是否有任何git命令可以查看guess_merge_tool()的输出,例如git merge guess-tool
  2. 是否有任何函数可以猜测diff工具,例如guess_diff_tool()
- ALittleDiff
  1. 这是一个 shell 函数,不是一个 git 命令。我猜你可以通过清除 merge.tool git 选项来看到这个文本。你总是可以进行打补丁。
  2. 相同的函数 guess_merge_tool 被用于不同的环境变量。浏览源代码,链接在问题中。
- KamilCuk
@Schwern,@KamilCuk,很抱歉我可能混淆了git diffgit difftool。我从未配置任何外部diff工具,也就是说,我一直依赖于git本身的内部实现。因此,对于这个问题的正确答案可能是:“默认的git diff工具是git本身”。 - ALittleDiff
1
@ALittleDiff git diff 不使用 git difftool - Schwern
1
@ALittleDiff,我已更新答案,以解释git diff和git difftool的工作原理。我认为这应该能够消除一些困惑。 - Schwern

2
我将补充一个在Schwern的答案中未提及的内容。
如果你的本地Git存储库处于“冲突检测状态”,“git difftool”将使用默认的git difftool。换句话说,在这种状态下,“git difftool”的工作方式与“git diff”完全相同。我不确定这是否是Git的错误,还是它应该起作用的预期方式。因此,当你处于“冲突检测状态”时,将忽略git difftool配置。这是我在“Git for Window”的2.37.x或2.38.x版本中观察到的行为。解决git冲突后,“git difftool”会重新使用配置的difftool。
以下是当你的本地git存储库处于“冲突检测状态”时可能看到的示例。
C:\Temp\user2\core>git pull remote: Enumerating objects: 58, done. remote: Counting objects: 100% (58/58), done. remote: Compressing objects: 100% (32/32), done. remote: Total 40 (delta 12), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (40/40), 3.13 KiB | 46.00 KiB/s, done. From c:\Temp\clone\core a7b9b22..6cce36f main -> origin/main Auto-merging CoreInterfaces/src/main/java/com/phinneyridge/core/Core.java CONFLICT (content): Merge conflict in CoreInterfaces/src/main/java/com/phinneyridge/core/Core.java Automatic merge failed; fix conflicts and then commit the result.
我猜当你处于冲突状态时,你可能不会看到Schwern的调试配置建议起作用。
我已经向Git社区提交了一个有关此问题的错误报告,我们将找出他们是否认为这种行为是错误还是按预期工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接