How do I setup DiffMerge with msysgit / gitk?
Asked Answered
A

4

21

I've just started using Git and it's possible I've missed something obvious, but here goes:

  • I'm using msysgit 1.6.2.2 on Windows XP
  • While installing, I picked option 1 to "Use Git Bash only"

I'm trying to put together a wrapper script that I can use to replace the built in git diff with DiffMerge. Based on this thread on SO, I created the following batch file:

@echo off
REM ---- Switch forward slashes to back slashes ----
set oldW=%2
set oldW=%oldW:/=\%
set newW=%5
set newW=%newW:/=\%

REM ---- Launch DiffMerge ----
"C:/Programs/SourceGear/DiffMerge/DiffMerge.exe" /title1="Old Version" %oldW% /title2="New Version" %newW%

I placed the bat file under %GIT_INSTALL%/cmd and edited my .gitconfig file as follows:

[diff]
external = C:/Programs/git/cmd/git-diff-wrapper.bat

If i launch Git Bash and execute git diff HEAD HEAD~ -- myfile

I get a message File (\dev\null) not found - which given I'm on Windows is not surprising.

Pressing on, I launched gitk and under Edit>Preferences, I chose the same wrapper script. Trying the "external diff" option for a particular file gives the cryptic error message Unknown Option "

Clearly, I have no idea what I'm doing anymore so any help would be much appreciated.

Aristocratic answered 23/4, 2009 at 5:40 Comment(1)
Just completed my answer with some "DiffMerge" specific elements, as requested.Megathere
M
9

I just experienced a somewhat similar experience with setting Notepad++ as my external editor with msysgit1.6.2.2.

The key was to realize the wrapper was not a DOS script, but a /bin/sh script.

So try to put in your ".bat" (even though it is not exactly a bat script, the extension is not important here):

#!/bin/sh

# diff is called by git with 7 parameters:
# path old-file old-hex old-mode new-file new-hex new-mode

"C:/Programs/SourceGear/DiffMerge/DiffMerge.exe" /title1="Old Version" "$2" /title2="New Version" "$5" | cat

Do not worry about making all the '\' go '/': it is done by the Git scripts calling the external diff tool.

I did not test it with DiffMerge, but with WinMerge, it works just fine, both from a DOS session or a Git Shell.

#!/bin/sh
"C:/Program Files/WinMerge/WinMergeU.exe" -e -ub "$2" "$5" | cat

(with the '-e' option, I have just ot type on 'ESC' to close and quit the diff tool: that works great!)


alt textaverage_geek adds in the comments:

added the '/bin/sh' header and tried running git diff again.
This time the error is:
Unexpected parameter 'C:/Docume~/avggeek/LOCALS~1/Temp/.diff_b08444
Is there a way to see what are the parameters getting passed when I call git diff ?

1/ There actually is a way to see what are the parameters getting passed!
Add the following line in the C:\Program Files\Git\libexec\git-core\git-sh-setup file:

git_editor() {
    : "${GIT_EDITOR:=$(git config core.editor)}"
    : "${GIT_EDITOR:=${VISUAL:-${EDITOR}}}"
    case "$GIT_EDITOR,$TERM" in
    ,dumb)
        echo >&2 "No editor specified in GIT_EDITOR, core.editor, VISUAL,"
        echo >&2 "or EDITOR. Tried to fall back to vi but terminal is dumb."
        echo >&2 "Please set one of these variables to an appropriate"
        echo >&2 "editor or run $0 with options that will not cause an"
        echo >&2 "editor to be invoked (e.g., -m or -F for git-commit)."
        exit 1
        ;;
    esac
#### ADD THIS LINE BELOW
    echo >&2 "editor is ${GIT_EDITOR:=vi} $@."
#### END ADDITION ABOVE
    eval "${GIT_EDITOR:=vi}" '"$@"'
}

You will see what editor is being called, with what parameter.

Now, regarding the "Unexpected parameter" part:
I did have the same kind of error when I called WinMergeU.exe with "/e /ub" instead of "-e -ub", so first question is:
Are you sure that the "/title1" bit could not be used as "-title1" or "-t1" or "--title1" or "--t1" ? That is what Is can see from the chapter 9 "Command Lines Arguments" of the pdf documentation of DiffMerge.
If not, I suspect some double quotes are in order for delimiting properly the different parameters. Something like:

"/title1="Old Version"" "$2" "/title2="New Version"" "$5"
or
"/title1=\"Old Version\"" "$2" "/title2=\"New Version\"" "$5"

But my money would rather be on the "-title1" or "-t1" form:

-t1="Old Version" "$2" -t2="New Version" "$5"

should work just fine.

Megathere answered 23/4, 2009 at 21:49 Comment(2)
I added the /bin/sh header and tried running git diff again. This time the error is: Unexpected parameter 'C:/Docume~/avggeek/LOCALS~1/Temp/.diff_b08444 Is there a way to see what are the parameters getting passed when I call git diff`?Aristocratic
"The key was to realize the wrapper was not a DOS script, but a /bin/sh script." For those like me not activating the "Use Git Bash only" option, it must be a Windows script (.cmd is more fashionable...) Same as your but using %2 instead of $2Ferdinand
C
15

I looked all over the internet for the answer to this. I tried all of the solutions above and elsewhere. I could get the merge part to work and not the diff part or vice versa. So what I did eventually was to hack together my own simple solution from all the info I got on the internet which works for me. It does not require any scripts only that you edit your .gitconfig which normally resides in the following directory C:\Documents and Settings\[username] You'll need to have DiffMerge program installed already.

Here is relevant extract of my .gitconfig file. You'll just need to edit the path to where your version of of DiffMerge is. Note that I used the old DOS 8.3 format in the path

[diff]
    tool = diffm
[difftool "diffm"]
    cmd = "H:/PROGRA~1/SourceGear/DiffMerge/DiffMerge.exe $LOCAL $REMOTE"
    prompt = false

[merge]
    tool = diffmerge
[mergetool "diffmerge"]
    cmd = "H:/PROGRA~1/SourceGear/DiffMerge/DiffMerge.exe --merge --result=$MERGED $LOCAL $BASE $REMOTE" 
    trustExitCode = false
    keepBackup = false

You can also set it up using the commands git config --replace --global [options] if you so wish.


This simple solution works perfectly for me, too. For more recent versions of DiffMerge (3.3.1), the command path needs to be changed:

    cmd = "C:/PROGRA~1/SourceGear/Common/DiffMerge/sgdm.exe ...etc..."
Chamness answered 27/5, 2011 at 21:30 Comment(3)
Props for a simple solution that just makes sense.Youngster
Like @Youngster said, +1 for simple solution that only requires editing .gitconfigClassmate
The key for me was changing ... /merge /replace=... to ... --merge --replace=...; SourceGear's docs seem to be wrong.Ashbaugh
M
9

I just experienced a somewhat similar experience with setting Notepad++ as my external editor with msysgit1.6.2.2.

The key was to realize the wrapper was not a DOS script, but a /bin/sh script.

So try to put in your ".bat" (even though it is not exactly a bat script, the extension is not important here):

#!/bin/sh

# diff is called by git with 7 parameters:
# path old-file old-hex old-mode new-file new-hex new-mode

"C:/Programs/SourceGear/DiffMerge/DiffMerge.exe" /title1="Old Version" "$2" /title2="New Version" "$5" | cat

Do not worry about making all the '\' go '/': it is done by the Git scripts calling the external diff tool.

I did not test it with DiffMerge, but with WinMerge, it works just fine, both from a DOS session or a Git Shell.

#!/bin/sh
"C:/Program Files/WinMerge/WinMergeU.exe" -e -ub "$2" "$5" | cat

(with the '-e' option, I have just ot type on 'ESC' to close and quit the diff tool: that works great!)


alt textaverage_geek adds in the comments:

added the '/bin/sh' header and tried running git diff again.
This time the error is:
Unexpected parameter 'C:/Docume~/avggeek/LOCALS~1/Temp/.diff_b08444
Is there a way to see what are the parameters getting passed when I call git diff ?

1/ There actually is a way to see what are the parameters getting passed!
Add the following line in the C:\Program Files\Git\libexec\git-core\git-sh-setup file:

git_editor() {
    : "${GIT_EDITOR:=$(git config core.editor)}"
    : "${GIT_EDITOR:=${VISUAL:-${EDITOR}}}"
    case "$GIT_EDITOR,$TERM" in
    ,dumb)
        echo >&2 "No editor specified in GIT_EDITOR, core.editor, VISUAL,"
        echo >&2 "or EDITOR. Tried to fall back to vi but terminal is dumb."
        echo >&2 "Please set one of these variables to an appropriate"
        echo >&2 "editor or run $0 with options that will not cause an"
        echo >&2 "editor to be invoked (e.g., -m or -F for git-commit)."
        exit 1
        ;;
    esac
#### ADD THIS LINE BELOW
    echo >&2 "editor is ${GIT_EDITOR:=vi} $@."
#### END ADDITION ABOVE
    eval "${GIT_EDITOR:=vi}" '"$@"'
}

You will see what editor is being called, with what parameter.

Now, regarding the "Unexpected parameter" part:
I did have the same kind of error when I called WinMergeU.exe with "/e /ub" instead of "-e -ub", so first question is:
Are you sure that the "/title1" bit could not be used as "-title1" or "-t1" or "--title1" or "--t1" ? That is what Is can see from the chapter 9 "Command Lines Arguments" of the pdf documentation of DiffMerge.
If not, I suspect some double quotes are in order for delimiting properly the different parameters. Something like:

"/title1="Old Version"" "$2" "/title2="New Version"" "$5"
or
"/title1=\"Old Version\"" "$2" "/title2=\"New Version\"" "$5"

But my money would rather be on the "-title1" or "-t1" form:

-t1="Old Version" "$2" -t2="New Version" "$5"

should work just fine.

Megathere answered 23/4, 2009 at 21:49 Comment(2)
I added the /bin/sh header and tried running git diff again. This time the error is: Unexpected parameter 'C:/Docume~/avggeek/LOCALS~1/Temp/.diff_b08444 Is there a way to see what are the parameters getting passed when I call git diff`?Aristocratic
"The key was to realize the wrapper was not a DOS script, but a /bin/sh script." For those like me not activating the "Use Git Bash only" option, it must be a Windows script (.cmd is more fashionable...) Same as your but using %2 instead of $2Ferdinand
T
8

This works for me with as follows:

In ~/.gitconfig:

[merge]
tool = diffmerge
[mergetool "diffmerge"]
cmd = \"C:/Program Files/git/cmd/git-diffmerge-merge.sh\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
trustExitCode = false

In C:\Program Files\Git\cmd\git-diffmerge-merge.sh:

#!/bin/sh

localPath="$2"
basePath="$1"
remotePath="$3"
resultPath="$4"

if [ ! -f $basePath ]
then
    basePath="~/diffmerge-empty"
fi

"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" --merge --result="$resultPath" "$localPath" "$basePath" "$remotePath" --title1="Mine" --title2="Merged: $4" --title3="Theirs"

Part of the credit goes to http://therightstuff.de/2009/01/28/Setting-Up-SourceGear-DiffMerge-With-Git.aspx ;)

Trilley answered 28/10, 2009 at 19:8 Comment(0)
A
4

VonC - switching to -t1 and -t2 fixed the errors. Diffmerge now works for git bash :)

After a little bit of poking at the gitk patch that added External Diff support, I realized that it's calling an External Diff program directly with the two files as arguments. So I modified gitk>Edit>Preferences and put the following command directly into the External Diff Tool option:

"C:/Programs/SourceGear/DiffMerge/DiffMerge.exe" -t1="Old Version" -t2="New Version"

Now I have DiffMerge working for gitk too :-)

Aristocratic answered 24/4, 2009 at 5:39 Comment(1)
With latest Diffmerge path is more likely "C:/Program Files/SourceGear/Common/DiffMerge/sgdm.exe" and -t1/-t2 does not work anymore. If you let that aside you get at least the comparison windowPericles

© 2022 - 2024 — McMap. All rights reserved.