What is the default git diff tool(and merge tool)?

3.2k Views Asked by At

What is the default git diff tool(and merge tool)?
Where(and how) can I find it out?

I've never set any configuration for git difftool(nor mergetool) explicitly,
so git config --get difftool shows nothing.

The git documentation says(https://git-scm.com/docs/git-difftool):

If the configuration variable diff.tool is not set, git difftool will pick a suitable default.

How can I find out which one it has picked?
How does the algorithm for 'suitable' work?


Let me share the reason why I'm trying to find out the currently picked diff tool by my git:
I've met some weird diff result when I execute git diff(I suspect BOM handling issue).
I'd like to question the vendor(e.g., p4merge) about it,
but not sure if it is p4merge, vimdiff or anything else.

I expect there might be a command like git difftool --current.

2

There are 2 best solutions below

5
On BEST ANSWER

git difftool will tell you what it's going to try.

$ 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]?

We can find the process in the guess_merge_tool function.

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 sets up the list of $tools. It assumes that if DISPLAY is not set you do not have a GUI which is incorrect on MacOS.

Then it simply loops through them and picks the first one it finds an executable for using type.


UPDATE

I've met some weird diff result when I execute git diff(I suspect BOM handling issue). I'd like to question the vendor(e.g., p4merge) about it, but not sure if it is p4merge, vimdiff or anything else.

If you're having an issue with git diff that is with git diff not git difftool. I think there's some confusion about what git difftool does, so here's a quick overview.

git diff does not use git-difftool. git difftool does not pick the diff tool for git diff. git diff has its own internal diff implementation. It can also use an external diff program, like GNU diff, by supplying --ext-diff.

When you run git difftool it picks an external diff program and runs it with three environment variables: $LOCAL, $REMOTE, and $MERGED. $LOCAL is a path to the old version of the file, $REMOTE to the new, and $MERGED to the name of the file so it can be displayed. That's about it. It has no relation to git diff.

We can see what git difftool does by adding to custom difftools to .gitconfig:

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

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

git difftool -t echo will show the environment variables. git difftool -t less will look at the contents of the old and new versions of the files in the less pager.


If you're having a problem with git diff, git difftool has nothing to do with it. Nor should p4merge nor vimdiff.

0
On

I'm going to add an additional remark that is not mentioned in Schwern's answer.

"git difftool" uses the default git difftool if your local Git repository is in the "conflict detected state". In other words, in that state, "git difftool" works exactly like "git diff". I'm not sure if this is a Git bug, or if that's the intended way it's supposed to work. So, when, you're in the "conflict detected state", the git difftool configuration is ignored. That's the behavior I witnessed in both version 2.37.x or 2.38.x of "Git for Window". Once you resolve the git conflict, "git difftool" goes back to using the configured difftool.

Here's an example of what you'll see when your local git repository is put in the "conflict detected state".

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.

I'm guessing you would not see Schwern's debugging configuration suggestion work if you try it when you're in the conflict state.

I've summited a bug to the Git community on this issue and we'll find out if they think that behavior is a bug or it's something that works as expected.