20

I'm using msys Git for source control on a Windows machine and I'm trying to figure out how to get my merge tool, WinMerge, to work with Git.

I've followed the instructions on this blog to the best of my ability since it's the closest I've found to what I'm trying to do. Basically what I did was:

Modify my .gitconfig file to include the following:

[merge]
    tool = winmerge

[mergetool "winmerge"]
    cmd = \"C:\\Program Files (x86)\\WinMerge\\WinMergeU.exe\" "$PWD/$LOCAL" "$PWD/$REMOTE" "$PWD/$MERGED"  
        trustExitCode = false  
    keepBackup = false

This is almost working. When I try to run the merge tool from Git, WinMerge gives me an error saying it can't find the paths of the files, which makes complete sense since the paths it is looking for are:

C:\MY\WORKING\DIRECTORY\-e
C:\MY\WORKING\DIRECTORY\-ub

It looks like Git is passing options into the merge tool instead of the local & remote file names that I would expect to get passed if everything was working correctly.

I've searched online for Git's merge documentation, but I can't seem to find anything related to what I'm trying to do. My guess is that the solution will be one of the following:

  1. Change the $LOCAL & $REMOTE variables to the correct values, assuming $LOCAL & $REMOTE are incorrect.
  2. Write a .bat script to call WinMergeU, and handle the arguments Git sends to the merge tool within the logic of my .bat script.
Dan Herbert
  • 99,428
  • 48
  • 189
  • 219

3 Answers3

12

If you look at the file that is conflicted, you'll notice the standard Theirs >>>>>>> and <<<<<< Mine markers. WinMerge understands these as merge conflicts, so it does not need 'Theirs' and 'Mine' to be specified explicitly; it just needs to be told which file it is that has the conflict markers.

  1. We know the file in the working directory contains the markers.
  2. It makes sense that the file we are merging to will also be this file - we also know that git mergetool makes the $MERGED variable available that names that file.

    [mergetool "winmerge"]
        cmd = 'C:/Program Files/WinMerge/WinMergeU.exe' \"$MERGED\"
    

This is all you need to hook git up with WinMerge for merge/conflict resolution; no scripts or command-line switches needed. Refer to the 3rd command-line form in the docs (linked by the OP, above) and the explanation of conflictfile argument.

Darren Bishop
  • 2,379
  • 23
  • 20
  • 1
    There is no right path? From the WinMerge docs `conflictfile Specifies a conflict file, typically generated by a Version control system. The conflict file opens in the File Compare window, where you can merge and resolve conflicts, as described in Resolving conflict files. Note that no other paths can be used with a conflict file.` (excuse the lame quoting) Perhaps you aren't using the latest version you only need to specify one file – Darren Bishop Jul 13 '10 at 12:00
  • Glad to be of help... did you vote, lol? Am I aloud to ask that? – Darren Bishop Jul 28 '10 at 16:24
  • Added this to my .gitconfig in my home folder (C:\Users\username\ on Windows), and was off to the races! Thanks. – BigBlueHat Mar 25 '13 at 17:04
7

From WinMerge Command line manual:

cmd = \"C:\\Program Files (x86)\\WinMerge\\WinMergeU.exe /ub /e \"
cmd = \"C:\\Program Files (x86)\\WinMerge\\WinMergeU.exe /u /e \"

(/u is the new /ub with latest WinMerge)

might work better as a command in your mergetool section.

However, you might have to wrap this call in a script, as described in this SO answer.

Extract adapted to merge.tool:

Practical case for configuring mergetool with your custom diff tool:

C:\myGitRepo>git config --global merge.tool winmerge
C:\myGitRepo>git config --global mergetool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\""
C:\myGitRepo>git config --global mergetool.prompt false

With winmerge.sh stored in a directory part of your PATH:

#!/bin/sh
echo Launching WinMergeU.exe: $1 $2
"C:/Program Files/WinMerge/WinMergeU.exe" -e -ub "$1" "$2"

If you have another tool (kdiff3, P4Diff, ...), create another shell script, and the appropriate mergetool.myMergeTool.cmd config directive.
Then you can easily switch tools with the merge.tool config.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • +1. (if I could. But at least I could undo my downvote... seems to be a [bug](http://meta.stackexchange.com/questions/23147/change-a-vote-from-downvote-to-upvote-via-editing)) actually, if you add winmerge to your path (or set `mergetool.winmerge.path` I guess) no script is needed – Tobias Kienzler Jul 07 '10 at 08:11
  • by the way, it should be `mergetool`, not `difftool` for this question – Tobias Kienzler Jul 07 '10 at 08:12
  • @Tobias: Thank you. Answer updated (`difftool` replaced by `mergetool`) – VonC Jul 07 '10 at 08:30
  • Natch add (x86) to path if you're using x64 Windows. Tried to add an edit to show what the .gitconfig file would look like if you edited it rather than used `git config --global` three times. Key lines in your .gitconfig: Under `[merge]` (adding bracketed sections if they don't exist) add `tool = winmerge` and under `[mergetool "winmerge"]` add `cmd = "wmDiff.sh \"$LOCAL\" \"$REMOTE\""` then `trustExitCode = false` then `keepBackup = false`. Also under `[mergetool]` (no "winmerge" after; new section) is `prompt = false`. Found editing .gitconfig to be easier for testing/optimzing options. – ruffin Apr 30 '12 at 15:21
5
[mergetool "winmerge"]
    cmd = winmergeu -e -ub -wl -dl "Remote" -dr "Local" "$PWD/$REMOTE" "$PWD/$LOCAL" "$PWD/$MERGED"
    keepBackup = false

If you look inside C:\Program Files\Git\share\git-gui\lib\mergetool.tcl it has syntax for common merge tools.

I'm still trying to figure out how to invoke mergetool directly from Git GUI...

hasen
  • 161,647
  • 65
  • 194
  • 231