52

I'm just starting to work with Git. I would like to use TortoiseMerge as the difftool and mergetool.

In my $HOME/.gitconfig I have the following sections. I've removed the user and color sections for this question.

[merge]
    tool = tortoisemerge
[mergetool "tortoisemerge"]
    cmd = \"TortoiseMerge.exe\" -base:\"$BASE\" -mine:\"$LOCAL\" -theirs:\"$REMOTE\" -merged:\"$MERGED\"
[diff]
    tool = tortoisemerge
[difftool "tortoisemerge"]
    cmd = \"TortoiseMerge.exe\" -base:\"$BASE\" -mine:\"$LOCAL\" -theirs:\"$REMOTE\" -merged:\"$MERGED\"

If I type tortoisemerge at the Git Bash prompt it loads. It is known to be on the path. But if I type the command I get the following error.

Rich:mygittest (master *)
$ git difftool
error: 'tortoisemerge' can only be used to resolve merges
merge tool candidates: kompare emerge vimdiff
No known merge resolution program available.
external diff died, stopping at readme.txt.
Rich:mygittest (master *)
$ 

What am I not understanding to make this work? Tortoisemerge is installed with TortoiseSVN.

user5534993
  • 518
  • 2
  • 17
Rich Shealer
  • 3,362
  • 1
  • 34
  • 59

7 Answers7

73

The following settings work fine for me. However, I am using TortoiseGit not TortoiseSVN. Notice the difference in the parameters for diff.

[diff]
  tool = tortoisediff
[difftool]
  prompt = false
[merge]
  tool = tortoisemerge
[mergetool]
  prompt = false
  keepBackup = false
[difftool "tortoisediff"]
  cmd = \""c:/Program Files/TortoiseGIT/bin/TortoiseGitMerge.exe"\" -mine "$REMOTE" -base "$LOCAL"
[mergetool "tortoisemerge"]
  cmd = \""c:/Program Files/TortoiseGIT/bin/TortoiseGitMerge.exe"\" -base "$BASE" -theirs "$REMOTE" -mine "$LOCAL" -merged "$MERGED"
Klas Mellbourn
  • 42,571
  • 24
  • 140
  • 158
  • 2
    TortoiseMerge has an issue with the way Git mangles the parameters. Because TortoiseMerge uses a colon to separate parameter name from value, Git puts quotes around both when dealing with filenames with spaces. TortoiseGitMerge allows a space and relieves the problem. – Rich Shealer May 11 '13 at 10:14
  • It is msys bash that mangles the quotes. Apparently it should work with tortoise git 1.8 – jwg Sep 12 '13 at 14:10
  • [Perforce can't cope with colons either](http://stackoverflow.com/a/12638596/284795). We should ask TortoiseMerge to add an alternative syntax. – Colonel Panic Aug 15 '14 at 09:13
  • It works for me when having `TortoiseSVN` which has `TortoiseMerge.exe`. Yes, `diff` with `TortoiseMerge.exe`, not `TortoiseIDiff.exe`. `git difftool` calls out TortoiseMerge GUI, very convenient! `TortoiseMerge` is the best! – WesternGun Nov 30 '17 at 17:09
7

So that filenames with spaces are handled correctly, you should change the last line of @melbourn's answer to

cmd = \""c:/Program Files/TortoiseGIT/bin/TortoiseGitMerge.exe"\" -base "$BASE" -theirs "$REMOTE" -mine "$LOCAL" -merged "$MERGED"
jwg
  • 5,547
  • 3
  • 43
  • 57
  • 1
    What's the difference? Is it (just) that the colons in the parameters have been replaced by spaces? Should a similar change be made for the difftool? I don't know if it's worth editing the original answer, or whether there is some reason for the colons.. – mwfearnley Aug 27 '14 at 22:33
  • 1
    The colons are replaced with spaces. The argument handling code can accept either colons or spaces. But quotes around a filename which has spaces in it will not be handled correctly if the quotes are not at either the start or the end of 'words'. – jwg Aug 31 '14 at 07:05
  • 3
    @jwg I have now modified my answer to take your advice into account. Thanks! – Klas Mellbourn Mar 26 '15 at 08:19
2

This is a simpler way, just run these commands in git bash:

git config --global merge.tool tortoisemerge

git config --global diff.tool tortoisediff
git config --global difftool.tortoisediff.cmd "TortoiseGitMerge \$LOCAL \$REMOTE"

It's done.

----for futher reading----

There are other settings you may need:

# you may want to disable prompt or merge backup
git config --global mergetool.keepBackup false
git config --global difftool.prompt false
git config --global mergetool.prompt false

# set the path only when it's not found in system path
git config --global mergetool.tortoisemerge.path "C:\Program Files\TortoiseGit\bin\TortoiseGitMerge.exe" 
git config --global difftool.tortoisdiff.path "C:\Program Files\TortoiseGit\bin\TortoiseGitMerge.exe"

To set the mergetool, you just need to set the right mergetool name. It's official supported.

Git for windows installer includes a shell file for running tortoisegitmerge as a merge tool. It locates at C:\Program Files\Git\mingw64\libexec\git-core\mergetools. (Git provides 4 variables for merging: $BASE $LOCAL $REMOTE $MERGED, you can check them in the shell file.)

You can check all supported merge/diff tools supported on your machine with the command:

git difftool --tool-help
git mergetool --tool-help

Run tortoisegitmerge as git diff tool is not official supported by git, maybe it's because this tool doesn't support directory compare (git difftool -d). So you need to config the difftool cmd to use it as a git difftool.

The tortoisegitmerge tool has a manual at:
https://tortoisegit.org/docs/tortoisegitmerge/tme-automation.html
You can find the simplest way to do diff file is:
TortoiseGitMerge BaseFilePath MyFilePath [ TheirFilePath ].
So I use this way for git difftool's command.

ws_
  • 1,076
  • 9
  • 18
0

Great answer by Klas Mellbourn! Saved me a lotta time. One shortcoming is, newly Added or Removed files in the repository will not show up during the difftool command execution. There's nothing to compare them to! Here's what I did on top of this: (Inspired by my co-worker's answer).

  1. Create a file named empty.empty in $Home directory (execute start ~ in your bash). And as the name suggests, keep it empty.
  2. Create another file named tortoisediff.sh in $Home/bin directory with following content

:

#!/bin/sh
# $LOCAL $REMOTE seem to be swapped
# $1 is $LOCAL
# $2 is $REMOTE

difftool='/c/Program Files/TortoiseGit/bin/TortoiseGitMerge.exe'
NULL="/dev/null"
empty="C:/home/empty.empty"

if [ "$1" == "$NULL" ]; then
    echo "Added: " "$2"
    "$difftool" /base:"$empty" /mine:"$2" /readonly:"$empty"
elif [ "$2" == "$NULL" ]; then
    echo 'Removed: ' "$1"
    "$difftool" /base:"$1" /readonly:"$1" /mine:"$empty"
else
    echo 'Modified' "$2"
    "$difftool" /base:"$1" /basename:"$1" /readonly:"$1" /mine:"$2" /minename:"$2"
fi

# Checkout https://tortoisegit.org/docs/tortoisegitmerge/tme-automation.html for more
  1. Modify your .gitconfig file (Line 11 of the answer)

    cmd = tortoisediff.sh "$LOCAL" "$REMOTE"

This would now make difftool refer to tortoisediff.sh instead of opening the application directly.

  1. Keep in mind: you'd have to run git add . followed by git difftool --staged instead of simply git difftool.
ThePatelGuy
  • 1,844
  • 1
  • 19
  • 18
0
[diff]
  tool = tortoisediff
[difftool]
  prompt = false
[merge]
  tool = tortoisemerge
[mergetool]
  prompt = false
  keepBackup = false
[difftool "tortoisediff"]
  cmd = \""C:/Users/$USER/Desktop/TortoiseMerge.exe"\" -base:\"$BASE\" -mine:\"$LOCAL\" -theirs:\"$REMOTE\" -merged:\"$MERGED\"
[mergetool "tortoisemerge"]
  cmd = \""C:/Users/$USER/Desktop/TortoiseMerge.exe"\" -base:\"$BASE\" -mine:\"$LOCAL\" -theirs:\"$REMOTE\" -merged:\"$MERGED\"

This worked for me, using TortoiseMerge 1.6.7 (Portable)

smooth_smoothie
  • 1,319
  • 10
  • 27
  • 40
0

When rebasing, I strongly recommend switch $theirs and $mine, because it is different when you merge and rebase-merge. Check here:

What is the precise meaning of "ours" and "theirs" in git?

So, if you only use mergetool to rebase like me, do:

[mergetool "tortoisemerge"]
cmd = \""c:/Program Files/TortoiseGIT/bin/TortoiseGitMerge.exe"\" -base "$BASE" -theirs "$LOCAL" -mine "$REMOTE" -merged "$MERGED"
WesternGun
  • 11,303
  • 6
  • 88
  • 157
0

For using the TortoiseMerge with an existing TortoiseSVN installation in Windows:

[guitool "VisualDiff"]
    cmd = git difftool -y \"$FILENAME\"
    needsfile = yes
    noconsole = yes
[diff]
    tool = tortoisediff
[difftool]
    prompt = false
[merge]
    tool = tortoisemerge
[mergetool]
    prompt = false
    keepBackup = false
[difftool "tortoisediff"]
    cmd = \""W:/Programs/TortoiseSVN/bin/TortoiseMerge.exe"\" "/mine:$REMOTE" "/base:$LOCAL"
[mergetool "tortoisemerge"]
    cmd = \""W:/Programs/TortoiseSVN/bin/TortoiseMerge.exe"\" "/base:$BASE" "/theirs:$REMOTE" "/mine:$LOCAL" "/merged:$MERGED"
wellsantos
  • 466
  • 4
  • 5