git difftool suddenly stopped working / how to troubleshoot?

2k views Asked by At

I have set up my git difftool to use winmerge. It has been working for quite a while. But it suddenly stopped working today. git difftool used to invoke winmerge on the dirty files one by one, but not today. The command just returned as if nothing happened. There were no error messages.

I double checked and indeed I have several dirty files (as shown by git status)

Any suggestions on how I can troubleshoot the problem? Thanks!

Updated

Thanks for the suggestion by fabspro. I made some progress but still have not been able to resolve the issue.

My original setting for winmerge as difftool was this (in my ~/.gitconfig file):

[diff]
      tool = winmerge

Now I understand that this will direct git difftool to use a script

C:\Program Files\Git\mingw64\libexec\git-core\mergetools

on my computer. I am going to show the contents of this script below. I believe the contents are in good shape since no one touched it, and it was working before today.

And then I also tried invoking WinMerge directly, so I change the directives in ~/.gitconfig to this

[diff]
        tool = mywinmerge
[difftool "mywinmerge"]
        cmd = "\"C:/Program Files (x86)/WinMerge/WinMergeU.exe\" \"$LOCAL\" \"$REMOTE\""

This idea came from this SO answer: https://stackoverflow.com/a/24337687/1168041

I double checked the path, and I also checked that in my git bash I could invoke WinMerge directly (without argument -- unlike the config above) using this command:

$ /c/Program\ Files\ \(x86\)/WinMerge/WinMergeU.exe

Still, I could not get my git difftool command to work (which was working yesterday)

Any more ideas? Thanks!

Appendix

Contents of my C:\Program Files\Git\mingw64\libexec\git-core\mergetools

diff_cmd () {
        "$merge_tool_path" -u -e "$LOCAL" "$REMOTE"
        return 0
}

merge_cmd () {
        # mergetool.winmerge.trustExitCode is implicitly false.
        # touch $BACKUP so that we can check_unchanged.
        touch "$BACKUP"
        "$merge_tool_path" -u -e -dl Local -dr Remote \
                "$LOCAL" "$REMOTE" "$MERGED"
        check_unchanged
}

translate_merge_tool_path() {
        # Use WinMergeU.exe if it exists in $PATH
        if type -p WinMergeU.exe >/dev/null 2>&1
        then
                printf WinMergeU.exe
                return
        fi

        # Look for WinMergeU.exe in the typical locations
        winmerge_exe="WinMerge/WinMergeU.exe"
        for directory in $(env | grep -Ei '^PROGRAM(FILES(\(X86\))?|W6432)=' |
                cut -d '=' -f 2- | sort -u)
        do
                if test -n "$directory" && test -x "$directory/$winmerge_exe"
                then
                        printf '%s' "$directory/$winmerge_exe"
                        return
                fi
        done

        printf WinMergeU.exe
}
2

There are 2 answers

3
leeyuiwah On BEST ANSWER

I've found my answer -- the problem was a false alarm. Sorry!

What happened was that I was confused by the exact semantics of git difftool.

Like git diff, git difftool shows the difference between the working directory and index, not the HEAD. When I ran my command, I have already staged my changes (i.e. put them into the index), so while there were differences from the HEAD, there were no differences from the index, hence the silent behavior of the command. The command that I should have used to show the diff is git difftool HEAD not just git difftool

I guess the moral of this story is this: If git difftool shows nothings, then try git diff. If the latter also shows nothings, then there probably are no differences, and probably nothing is wrong with the configuration of git difftool

I would like to conclude this answer with the following wonderful picture from "A Visual Git Reference" that can serve as a good reminder of the exact semantics of git diff vs git diff HEAD

enter image description here

0
fabspro On

As per the discussion in the comments, troubleshooting an external tool can be done by checking the basics - is it configured, is the tool working if you start it by itself, is the tool in the system path/is the correct path to the tool configured in the git config.