Ruben Laguna's blog

Aug 5, 2010 - 2 minute read

DiffMerge/WinMerge for Cygwin Git

After reading several blogs and pages I got SourceGear DiffMerge and WinMerge working with Cygwin’s Git.

First you need to put some scripts in the path that serve as wrapper for invoking DiffMerge and WinMerge.

I created 2 wrapper scripts for DiffMerge diffmerge-diff.sh and diffmerge-merge.sh See the source code in the gist.

I also created two more scripts for WinMerge: winmerge-diff.sh and winmerge-merge.sh. You can find the source code for scripts in the same gist.

All four scripts rely on githelperfunction.sh to properly convert the path and set variables.

The scripts above take into account:

  • Conversion of cygwin paths to Windows path
  • Handle filenames with whitespace
  • Handle properly non-existing files. Sometimes a file doesn’t exist in one of the branches you are comparing and then git will provide /dev/null as filename for that one. These scripts take care of converting that to a proper empty file in Windows.
  • DiffMerge: Set the window title in DiffMerge to the filename. And set labels for each file window to LOCALFROM_VERSION, REMOTETO_VERSION and BASEMERGED
  • WinMerge: Set the file labels to LOCALFROM_VERSION.filename and REMOTETO_VERSION.filename.

After storing those script and make them accessible from your $PATH then you need to tell git how to use them.

You can use the following commands to tell git about this wrappers:

# for difftool
git config --global difftool.diffmerge.cmd "diffmerge-diff.sh \"\$LOCAL\" \"\$REMOTE\"" \"\$BASE\"" \"\$MERGED\""
git config --global difftool.winmerge.cmd "winmerge-diff.sh \"\$LOCAL\" \"\$REMOTE\"" \"\$BASE\"" \"\$MERGED\""
git config --global difftool.prompt false


# for mergetool
git config --global mergetool.diffmerge.cmd "diffmerge-merge.sh \"\$LOCAL\" \"\$REMOTE\"" \"\$BASE\"" \"\$MERGED\""
git config --global mergetool.diffmerge.trustExitCode false
git config --global mergetool.winmerge.cmd "winmerge-merge.sh \"\$LOCAL\" \"\$REMOTE\"" \"\$BASE\"" \"\$MERGED\""
git config --global mergetool.winmerge.trustExitCode false

And then you can invoke git difftool and git mergetool using -t <TOOL> to indicate which one you want to use:

git difftool -t diffmerge
git difftool -t winmerge
git mergetool -t diffmerge
git mergetool -t winmerge

if you want to make any of those tools the default you can use git config to do so:

git config --global diff.tool winmerge
git config --global merge.tool diffmerge

Hope this helps