How can I make WinMerge my git mergetool?
Asked Answered
B

16

70

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
Bluegill answered 23/5, 2012 at 5:24 Comment(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)?Ripple
Note: with Git 2.5+ (Q2 2015), Winmerge will be a known diff or merge tool! See my answer belowPruchno
P
81

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.

Power answered 1/5, 2013 at 23:4 Comment(9)
On winmerge link, it says supports 3-way merges only by command line, so for git purposes it's okUnbelt
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.Teller
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).Quirinal
@Unbelt Since 2.16.0 (released 4 days ago), it fully supports 3-way merges (also in the GUI).Footstone
@Footstone do you know if there is a change in the config? or what is the right config parameters for 2.16 ?Phung
@ObmerkKronen There is no change, above answer is valid.Footstone
To get this working in Powershell, just replace the outermost double quotes with single quotes.Autarky
WinMerge didn't get the path to the files. i'm using Git Bash. probably related to what @AndrewTheken saidAesir
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...).Methodist
P
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
Prohibition answered 11/7, 2014 at 16:51 Comment(1)
There is another set of command line options here: community.atlassian.com/t5/Questions/… This does the same thing, just slightly different layout in WinMerge.Stolon
P
39

Git 2.5+ (Q2 2015) will include Winmerge (the entry 'winmerge', not the actual binary) as a known git mergetool entry!

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 demands 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.

Pruchno answered 7/6, 2015 at 22:46 Comment(15)
The thread also points to this configuration which completely solved the case for me. Thanks,Valarievalda
@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.Tripedal
@hlp not sure, considering the diff would be the all file anyway. Consider posting a separate question for this.Pruchno
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...Hypercatalectic
@Hypercatalectic Try first to upgrade to the latest Git for Windows, 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.Pruchno
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, 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.Misinterpret
@Misinterpret True, but you might consider configuring WinMerge as mergetool using a wrapper: See my gist for the explanation.Pruchno
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 #1853Misinterpret
@Misinterpret Nice: I am following your discussion in that thread. Let me know when you want me to edit my answer and include your conclusion.Pruchno
@Pruchno please do it. Thanks. I think a lot of people who used winmerge did not know this, so sharing is great.Misinterpret
@Misinterpret I have done a first edit: can you edit the answer to include your current WinMerge setting? I will review and approve your edit.Pruchno
OK, I have added what I have used command line option for git mergetool in your answer.Misinterpret
@Misinterpret Thank you for your edit and feedback. Edit approved.Pruchno
When you say " will include Winmerge as a known git mergetool" I'm assuming you don't mean the binaries are bundled in the git package, but that git instinctively will look for it in standard locations.Advisee
@SridharSarnobat Yes, winmerge as a mergetool entry, not WinMerge the binary. I have edited the answer to make that clearer.Pruchno
G
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\"
Gubernatorial answered 23/5, 2012 at 5:56 Comment(6)
I'm a total git newbie. That looks like it's from some config file (like .ini file). Can you mention where it is?Taillight
Seems I found it :) this file is apparently in ~/.gitconfig which on Windows seems to be my user folder ie: c:\users\myuserfolder\Taillight
Why do you open the files as read only? (-wl -wr) Surly that defeats the point of merging?Exiguous
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.Gubernatorial
This is for a difftool. The question is asking for a mergetoolTeller
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.Dermato
L
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
Letitialetizia answered 1/5, 2013 at 2:21 Comment(3)
I think $LOCAL and $REMOTE are swapped in this version.Plexus
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)Jigsaw
I omitted the -dl "Base" so one side shows the file name. The other still gets labelled "Mine" so it's clearDevilment
A
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
Amarillas answered 25/7, 2018 at 6:54 Comment(0)
M
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.

Mnemonic answered 2/7, 2019 at 12:33 Comment(1)
Thank you. This is the only config that works with Visual Studio 2019.Electroacoustics
M
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.

Medical answered 23/5, 2012 at 5:41 Comment(0)
U
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
Urion answered 12/9, 2019 at 11:37 Comment(1)
/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.Courcy
P
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.

Prohibition answered 5/3, 2019 at 18:4 Comment(1)
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.Courcy
C
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"
Corallite answered 29/7, 2022 at 19:39 Comment(1)
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.Misinterpret
O
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

Operation answered 2/7, 2014 at 14:30 Comment(0)
S
1

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 :)

Sheerness answered 20/7, 2023 at 6:18 Comment(0)
J
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
Jigsaw answered 13/10, 2014 at 19:7 Comment(0)
I
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
Innings answered 24/9, 2021 at 10:44 Comment(0)
M
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 ...

Musicianship answered 14/1, 2022 at 11:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.