68

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
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Wei Jin
  • 701
  • 1
  • 6
  • 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

16 Answers16

80

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
  • 51,991
  • 13
  • 150
  • 199
  • 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
  • 6
    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
  • 4
    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
41

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
  • 411
  • 4
  • 2
  • 1
    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
38

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.


Update on 2023-05-17, I think the best command line is below:

"C:/Program Files/WinMerge/winmergeu.exe" -e -u -am -wl -wr -fm -dl "Mine: $LOCAL" -dm "Merged: $BASE" -dr "Theirs: $REMOTE" "$LOCAL" "$BASE" "$REMOTE" -o "$MERGED"

Please note that the -am is used, which means "auto merge on the middle panel".
The "$LOCAL" "$BASE" "$REMOTE" means show three panels, from left to right, the common base is shown in the middle panel but WinMerge will auto merge it.
-o "$MERGED" means when we close the WinMerge, the middle panel's content will write to the final file (the one you are trying to fix conflicts).

Note: ollydbg23 asks in the comments and in WinMerge/winmerge discussion 1853:

There is one issue that after the merge, winmerge dose not give notification if it still has conflicts in the final file.

Hence, the feature request 1855.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 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
  • Has anyone had trouble getting "git config diff.tool winmerge" to work within gitbash on Windows? With my git version "2.33.1.windows.1" the command "git diff ..." just keeps using the basic text diff, and I can't figure out why it's not working as advertised above... – spechter Jan 31 '23 at 04:20
  • @spechter Try first to upgrade to [the latest Git for Windows](https://github.com/git-for-windows/git/releases), 2.39.1. Check also `git config -l --show-scope --show-origin|grep -i diff`, to see if there is settings which might override one another. – VonC Jan 31 '23 at 07:10
  • I have 64bit winmerge, and it is not in the PATH, so I need to know how to config it. I'm using `git version 2.40.0.windows.1`, someone suggested that I should use [this configuration](https://gist.github.com/shawndumas/6158524), but it looks like I need to change the position of the last three elements as: `$LOCAL $MERGED $REMOTE`, so that the merged file which normally contains `<<<<<<<` or `>>>>>>>>` will shown in the middle panel of the winmerge. But it looks like winmerge doesn't give me notification if there are still conflicts when I close it. – ollydbg23 May 15 '23 at 10:13
  • @ollydbg23 True, but you might consider configuring WinMerge as `mergetool` using a *wrapper*: See [my gist for the explanation](https://gist.github.com/VonC/a802b9668d6b94dfb2573b0a78911bce). – VonC May 15 '23 at 12:15
  • Thanks, I have update the comment there. Meanwhile, some winmerge dev gives me another idea on how to use winmerge as mergetool, especially, as suggest the auto merge option, which is `-am`. See here: [What is the correct way to config winmerge as merge tool under Windows, and using git-for-windows · WinMerge/winmerge · Discussion #1853](https://github.com/WinMerge/winmerge/discussions/1853) – ollydbg23 May 16 '23 at 01:35
  • @ollydbg23 Nice: I am following your discussion in that thread. Let me know when you want me to edit my answer and include your conclusion. – VonC May 16 '23 at 13:54
  • @VonC please do it. Thanks. I think a lot of people who used winmerge did not know this, so sharing is great. – ollydbg23 May 16 '23 at 23:07
  • @ollydbg23 I have done a first edit: can you edit the answer to include your current WinMerge setting? I will review and approve your edit. – VonC May 17 '23 at 10:02
  • OK, I have added what I have used command line option for git mergetool in your answer. – ollydbg23 May 17 '23 at 14:03
  • @ollydbg23 Thank you for your edit and feedback. Edit approved. – VonC May 17 '23 at 14:28
17

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
  • 4,333
  • 2
  • 17
  • 29
  • 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
  • 6,271
  • 5
  • 40
  • 46
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
7

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
  • 7,142
  • 6
  • 42
  • 56
Zin Min
  • 3,898
  • 1
  • 20
  • 24
7

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,833
  • 2
  • 23
  • 30
6

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
  • 915
  • 1
  • 6
  • 16
5

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
  • 952
  • 11
  • 8
  • /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
4

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.

CapinWinky
  • 748
  • 7
  • 8
  • 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

If you decided to use fork client, you could use these settings:

File -> Preferences -> Integration ->

  • Merge Tool -> Custom

Merger Path

C:\Program Files\WinMerge\WinMergeU.exe

Arguments

-e -u -dl "Mine" -wr -dm "Merged" -dr "Theirs" $LOCAL $MERGED $REMOTE
  • External Diff Tool -> Custom

Merger Path

C:\Program Files\WinMerge\WinMergeU.exe

Arguments

-u -dl "Local" -dr "Remote" "$LOCAL" "$REMOTE"
Yaman
  • 1,030
  • 17
  • 33
  • I think `$LOCAL $MERGED $REMOTE` this is the correct option. I mean `$MERGED` file should be put in the middle panel, and this file should have many content that git already git merged, and some special part git will marked as `>>>>>` or `<<<<<` as conflicts, so we can manually edit the conflict parts. – ollydbg23 May 16 '23 at 01:43
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
  • 26,542
  • 16
  • 152
  • 170
andersonbd1
  • 5,266
  • 14
  • 44
  • 62
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
  • 8,648
  • 5
  • 43
  • 56
0

Here the only one working for me with Visual Studio 2019 and my winmerge 2.16.14.0: C:\Users\CurrentUserAccount\.gitconfig

[difftool "winmerge"]
name = WinMerge
trustExitCode = true
    cmd = \"C:\\Program Files (x86)\\WinMerge\\WinMergeU.exe\" -e -u  \"$LOCAL\" \"$REMOTE\"
[diff]
    tool = winmerge
[difftool]
    prompt = false

Additional thing to check: file MySolution.git\config (yes, the file name is "config" without extension): Verify if you have:

[diff]
tool = winmerge

You can modify it with the following command (Visual studio Menu "Git"\Open in Command Prompt":

git config diff.tool winmerge
0

So, I've never used a three-window-mode for merging and was able to configure everything with help above but as nowadays with a Winmerge 2.16.16.0 I was able to get desired behavior only with 'Open conflict File' option. The git config for it is:

cmd = \"c:/Programs/WinMerge/WinMergeU\" -e $MERGED

As for me this it is the best speed/usability option without manual handling of those special markers ...

0

so I found out how to install the WinMerge to GitConfig as a mergetool and difftool, here's the step with git bash command:

  1. Set the merge tool in GitConfig

git config --global merge.tool WinMerge

  1. Set the WinMerge path, according to where your WinMerge was installed, Mine was at program files

git config --global mergetool.WinMerge.path "C:\Program Files\WinMerge\WinMergeU.exe"

  1. Set the mergetool.prompt to false

git config --global mergetool.prompt false

  1. Set the difftool in git config

git config --global diff.tool WinMerge

  1. Set the difftool path,

git config --global difftool.WinMerge.path "C:\Program Files\WinMerge\WinMergeU.exe"

  1. Set the difftool prompt to false

git config --global difftool.prompt false

Now you can do:

  1. git mergetool
  2. git difftool

happily :)

Vincent
  • 21
  • 4