57

I'm trying to integrate WinMerge with Git as I've seen others done before on Windows 7 Ultimate.

I've followed the following steps, but an error continues to show up when I do a git mergetool which defaults to vimdiff.

Created a file called winmerge.sh in the root directory of git: C/Program Files (x86)/Git/ with: WinMergeU is the correct location.

#!/bin/sh
echo Launching WinMergeU.exe: $1 $2
"C:/Program Files (x86)/WinMerge/WinMergeU.exe" 
git /e /u /dl "Base" /dr "Mine" "$1" "$2"

and used the following commands.

git config --global diff.tool winmerge
git config --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\""
git config --global difftool.prompt false

The error shows up as:

git config option merge.tool set to unknown tool: winmerge
Elrond_EGLDer
  • 47,430
  • 25
  • 189
  • 180
Wei Jin
  • 591
  • 1
  • 5
  • 3
  • 2
    Is winmerge.sh available in your $PATH? And what command got you this error (The error shows up as: git config option merge.tool set to unknown tool: winmerge)? – positron May 23 '12 at 05:33
  • Note: with Git 2.5+ (Q2 2015), Winmerge will be a known diff or merge tool! See [my answer below](http://stackoverflow.com/a/30699239/6309) – VonC Jun 07 '15 at 22:49

12 Answers12

69

You are talking about merge tool, yet you (and some other people with answers) are configuring it as a diff tool.

To configure a merge tool, you'd need to use merge.tool and mergetool configurations instead of diff.tool and difftool, like this:

git config --global merge.tool winmerge
git config --replace --global mergetool.winmerge.cmd "\"C:\Program Files (x86)\WinMerge\WinMergeU.exe\" -e -u -dl \"Base\" -dr \"Mine\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\""
git config --global mergetool.prompt false

And then you can use

git mergetool

which will open you the two files to edit.

Kudos for @dvdvck mentioning in the comments that in command line parameters you can specify a third file for the result file for winmerge (outputpath parameter).

For completeness, I'll mention that there is also this gist aimed at full configuration of winmerge for both as diff and merge tool.

eis
  • 45,245
  • 11
  • 129
  • 177
  • 4
    On winmerge link, it says supports 3-way merges only by command line, so for git purposes it's ok – dvdvck Jul 30 '14 at 21:38
  • 4
    Depending on which shell you are using (bash, for example), the escaping of *$LOCAL*, *$REMOTE*, and *$MERGED* might not produce the correct result in your .gitconfig, you can go in and edit it by hand, but otherwise, the above works well. – Andrew Theken Aug 08 '16 at 14:28
  • To elaborate on @AndrewTheken comment: the above config command for mergetool.winmerge.cmd works correctly on Windows Command Prompt (cmd.exe), but not Bash (produces incorrect config due to variable expansion) or Powershell (does not even run due to (x86) part in the path). – Sergii Volchkov Jul 14 '17 at 13:36
  • @dvdvck Since 2.16.0 (released 4 days ago), it fully supports 3-way merges (also in the GUI). – Jona Nov 26 '18 at 12:33
  • @Jona do you know if there is a change in the config? or what is the right config parameters for 2.16 ? – Obmerk Kronen Mar 25 '19 at 13:41
  • @ObmerkKronen There is no change, above answer is valid. – Jona Mar 25 '19 at 16:24
  • 1
    To get this working in Powershell, just replace the outermost double quotes with single quotes. – lesscode Jul 31 '19 at 20:34
  • WinMerge didn't get the path to the files. i'm using Git Bash. probably related to what @AndrewTheken said – RZKY Sep 19 '19 at 03:15
  • Yeah (cc @RZKY) when doing this from bash in Windows I also had to escape the $ signs. Nbd. Also I find it is easier to use with the MERGED file in the middle instead of the REMOTE. I did: `git config --global mergetool.winmerge.cmd "\"c:\\program files (x86)\\winmerge\\winmergeu.exe\" -e -u -dl \"Base\" -dr \"Mine\" \"\$LOCAL\" \"\$MERGED\" \"\$REMOTE\""` -- same as the answer just with `\$`'s, and MERGED / REMOTE swapped. Then it worked. (PS Was also pleasantly surprised that the native pathname worked even from bash, as opposed to `/c/Prograblahblah...`). – Jason C Apr 18 '21 at 15:46
34

If you decide to use SourceTree (or for any Google searchers with SourceTree), you can use WinMerge for the Merge Tool by setting the Merge Tool to custom, pointing Diff Command to WinMergeU.exe, typically:

C:\Program Files (x86)\WinMerge\WinMergeU.exe

In Arguments use:

-e -u -dl "Mine" -wr -dr "Theirs" $LOCAL $REMOTE $MERGED

That will cause the left side (labeled "Mine") to be editable and it will be the output file when you save in WinMerge. The right side (labeled "Theirs") will be read only (that's the -wr argument), this is needed because WinMerge outputs all saved files to the $MERGED file, so if both sides were edited, it would output the left side then overwrite that with the right side; best to avoid that kind of confusion.

If you leave the backup file option turned on, WinMerge will generate a .bak file. The contents of this file will either be the original left side file, or the second to last output file if you saved multiple times. You can either turn this off, or add *.bak to your .gitignore file.

Git itself will create a *.orig conflict file AFTER the conflict is resolved, just in case you botched it. Again, you can add *.orig to your .gitignore file or turn off this feature. Unfortunately, SourceTree does not have a GUI option for this, so fire up your git bash or, if you chose the right PATH option during installation, the Windows Command prompt and do this:

git config --global mergetool.keepBackup false

That will stop Git creating the *.orig files. You can also directly edit the config file by locating the .gitconfig file in the root of your user directory. If you know how to use VIM, you can edit the whole thing with this command:

git config --global --edit
CapinWinky
  • 341
  • 3
  • 2
  • There is another set of command line options here: https://community.atlassian.com/t5/Questions/Can-t-launch-external-merge-tool-WinMerge-on-Windows/qaq-p/315156 This does the same thing, just slightly different layout in WinMerge. – Eric Burdo Sep 09 '19 at 15:01
30

Git 2.5+ (Q2 2015) will include Winmerge as a known git mergetool!

If Winmerge is in your %PATH%, a git config merge.tool winmerge is all you need to do!
(It works for diff tool too: git config diff.tool winmerge)

See commit 3e4f237 by David Aguilar (davvid), 20 May 2015.
(Merged by Junio C Hamano -- gitster -- in commit 324a9f4, 01 Jun 2015)
Helped-by: Philip Oakley (PhilipOakley), Johannes Schindelin (dscho), Sebastian Schuberth (sschuberth), SZEDER Gábor (szeder)

All the config is now done for you directly in Git itself, with mergetools/winmerge:

  • diff command: "$merge_tool_path" -u -e "$LOCAL" "$REMOTE"
  • merge command: "$merge_tool_path" -u -e -dl Local -dr Remote "$LOCAL" "$REMOTE" "$MERGED"

mergetools: add winmerge as a builtin tool

Add a winmerge scriptlet with the commands described in this thread, so that users can use winmerge without needing to perform any additional configuration.

Community
  • 1
  • 1
VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
  • 3
    The thread also points to [this configuration](https://gist.github.com/shawndumas/6158524) which completely solved the case for me. Thanks, – faidherbard Aug 07 '15 at 17:29
  • @VonC, do you know how to get git to show diff for newly added files? For a newly added file, winmerge shows a dialog with `\\.\nul` as one of the path which is invalid. So winmerge does not even show the diff. – hIpPy Oct 12 '16 at 19:58
  • @hlp not sure, considering the diff would be the all file anyway. Consider posting a separate question for this. – VonC Oct 12 '16 at 21:01
15

Here's mine (in %userprofile%\.gitconfig, or ~/.gitconfig on *nix), no wrapper (Win 7 Home Pro):

[diff]
    tool = winmerge
[difftool "winmerge"]
    cmd = c:/path/to/winmergeu.exe -e -u -x -wl -wr -dl "base" -dr "mine" \"$LOCAL\" \"$REMOTE\"
ellotheth
  • 3,803
  • 1
  • 15
  • 28
  • I'm a total git newbie. That looks like it's from some config file (like .ini file). Can you mention where it is? – aikeru Jan 27 '13 at 18:33
  • 2
    Seems I found it :) this file is apparently in ~/.gitconfig which on Windows seems to be my user folder ie: c:\users\myuserfolder\ – aikeru Jan 27 '13 at 18:40
  • Why do you open the files as read only? (-wl -wr) Surly that defeats the point of merging? – BJury Jun 16 '14 at 10:57
  • 3
    In the config sample, WinMerge is configured as `difftool`, which is for read-only viewing of the diff. Check @eis' answer for details about merging. – ellotheth Jun 16 '14 at 21:29
  • 1
    This is for a difftool. The question is asking for a _mergetool_ – Andrew Theken Aug 08 '16 at 14:25
  • I've tried this and I get Winmerge opening with a "Select Files or Folders" dialog, the Left file is filled in and the Right: file is empty. – Ed Randall Sep 30 '16 at 12:58
7

This is easier to do and is what worked for me:

git config --global diff.tool winmerge

git config --replace --global difftool.winmerge.cmd "\"C:\path to winmerge\WinMergeU.exe\" -e -u -dl \"Base\" -dr \"Mine\" $LOCAL $REMOTE"

git config --global difftool.prompt false
John Rix
  • 4,931
  • 3
  • 35
  • 39
gman
  • 71
  • 1
  • 1
  • 1
    I think $LOCAL and $REMOTE are swapped in this version. – Tom Sep 24 '13 at 06:45
  • 1
    Tom, not only that, but the backslash right before the $REMOTE and $LOCAL variables is causing a problem with WinMerge (I'm using latest version 2.14.0.0 as of now) – zumalifeguard Oct 13 '14 at 19:05
  • I omitted the `-dl "Base"` so one side shows the file name. The other still gets labelled `"Mine"` so it's clear – GregHNZ Nov 09 '15 at 22:03
6

To do WinMerge as compare and merge tool for Visual Studio 2017 Git Plugin:

From windows command prompt: type >> git config --global --edit which will open the .getconfig file to edit.

Please update with below command:

[mergetool]
   prompt = false
   keepBackup = false
   keepTemporaries = false
[merge]
   tool = winmerge
   [mergetool "winmerge"]
   name = WinMerge
   trustExitCode = true
   cmd = \"C:\\Program Files (x86)\\WinMerge\\WinMergeU.exe\" -e -u -dl \"Base\" -dr \"Mine\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
[diff]
   tool = winmerge
   [difftool "winmerge"]
   name = WinMerge
   trustExitCode = true
   cmd = \"C:\\Program Files (x86)\\WinMerge\\WinMergeU.exe\" -u -e $LOCAL $REMOTE
DeanOC
  • 6,782
  • 6
  • 40
  • 52
Zin Min
  • 1,942
  • 16
  • 24
4

Your path is incorrect, it should be "/c/Program Files (x86)/WinMerge/WinMergeU.exe".

You're running in a shell script environment, not native windows command prompt.

Thach Mai
  • 875
  • 6
  • 15
3

After installing TortoiseGit and WinMerge 2.16 (this version supports 3-way merging), I found how WinMerge integrate itself to TortoiseGit:

D:\Program Files\WinMerge\WinMergeU.exe /e /ub /fm /wl /wr /dl %tname /dm %bname /dr %yname  %theirs %base %mine /o %merged /am

So I edited the .gitconfig file and change some vars to make it work for me (I added WinMerge dir to the system path):

[mergetool "winmerge"]
    cmd = WinMergeU -e -ub -fm -wl -wr $LOCAL $BASE $REMOTE -o $MERGED -am
trank
  • 654
  • 7
  • 7
  • /ub is not a valid flag. Also I'm not sure if you would want to auto-merge the base (/am flag). I don't think that makes too much sense. Though I'm still not 100% clear on what the /ar /am /al auto merge flags actually do. – BigDru Jan 26 '21 at 16:20
2

Entering the settings via the command line has been covered by other answers. The .gitconfig file for full 3-way merging with WinMerge could be configured like this (this example is from Windows):

[merge]
    tool = WinMerge

[mergetool "WinMerge"]
    cmd = \"C:\\Program Files\\WinMerge\\WinMergeU.exe\" -e -u -dl \"Local\" -dm \"Base\" -dr \"Remote\" \"$LOCAL\" \"$BASE\" \"$REMOTE\" -o \"$MERGED\"
    trustExitCode = true
    keepBackup = false

[diff]
    tool = WinMerge

[difftool "WinMerge"]
    cmd = \"C:\\Program Files\\WinMerge\\WinMergeU.exe\" -e -u -dl \"Old $BASE\" -dr \"New $BASE\" \"$LOCAL\" \"$REMOTE\"
    trustExitCode = true

Flag information:

  • /e - Allows WinMerge to be closed via a single press of the 'esc' key.
  • /u - Prevents WinMerge from logging the files in the recently used list.
  • /dl, /dm, and /dl - Descriptions for Left, Middle, and Right panes.
  • /o - The output file. Saving ANY pane will output that pane's contents to the output file.

trustExitCode = true tells git to accept the output without further prompt.

keepBackup = false will automatically delete the automatically generated *.orig files.

Note: The $BASE and $MERGE variables when using difftool both simply contain the filename.

Isaac Brown
  • 407
  • 4
  • 6
  • Thank you so much. I wish I paid more attention to the /o flag description when I read it. This response has cleared everything up for me. – BigDru Jan 26 '21 at 16:30
2

I originally upvoted @CapinWinky's answer for using WinMerge from SourceTree. That answer is still valid, but WinMerge now also supports a three-way merge which needs additional parameters.

Within the SourceTree Options dialog I chose "Custom" as the Merge Tool, entered the command as:

C:\Program Files\WinMerge\WinMergeU.exe

and the Arguments as:

-u -fm -wl -wr -dl Remote_RO -dm Local_Merged -dr Base_RO $REMOTE $LOCAL $BASE -o $MERGED

It doesn't seem to be necessary to enclose the remote/local/base parameters in quotes to cater for paths with spaces in them any more.

This configuration is for using the middle pane as the merged output file.

Command line reference

I had the problem that when trying to merge, WinMerge wouldn't open. Sourcetree starts Git to open your tool of choice. When using Sourcetree's custom option, your git config file (e.g. C:\Users\Me\.gitconfig) is modified to add a new Merge tool called "sourcetree" and the Git command includes --tool=sourcetree . At some point the .gitconfig file hadn't been updated correctly and I had two 'cmd' lines in that section, one being broken:

[mergetool "sourcetree"]
    cmd = 'C:/Program Files/WinMerge/WinMergeU.exe' -u -fm -wl -wr -dl Remote_RO -dm Local_Merged -dr Base_RO $REMOTE $LOCAL $BASE -o $MERGED
    trustExitCode = true
    cmd = 'C:/Program '

Manually fixing up the .gitconfig file sorted the problem.

Daz
  • 2,438
  • 1
  • 16
  • 23
1

After hassling with this for over an hour, I installed tortoisegit and so far it's giving me exactly what I want.

Settings of Winmerge for Tortoise git are described in http://thoai-nguyen.blogspot.com.au/2012/03/setup-tortoise-git-and-winmerge.html

Michael Freidgeim
  • 21,559
  • 15
  • 127
  • 153
andersonbd1
  • 4,985
  • 13
  • 39
  • 59
0

Example:

git config --global --add diff.tool winmerge
git config --replace --global difftool.winmerge.cmd "\"C:\Program Files (x86)\WinMerge\WinMergeU.exe\" -e -u -dl \"Base\" -dr \"Mine\" $LOCAL $REMOTE"
git config --global difftool.prompt false
zumalifeguard
  • 7,799
  • 5
  • 31
  • 46