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
}
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 isgit difftool HEAD
not justgit difftool
I guess the moral of this story is this: If
git difftool
shows nothings, then trygit diff
. If the latter also shows nothings, then there probably are no differences, and probably nothing is wrong with the configuration ofgit 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
vsgit diff HEAD