Contact

admin

About Me · Send mail to the author(s) E-mail · Twitter

At GROSSWEBER we practice what we preach. We offer trainings for modern software technologies like Behavior Driven Development, Clean Code and Git. Our staff is fluent in a variety of languages, including English.

Feed Icon

Tags

Open Source Projects

Archives

Blogs of friends

Now playing [?]

  1. Pink Floyd – Run Like Hell
  2. Pink Floyd – Comfortably Numb
  3. Pink Floyd – Wish You Were Here
  4. Pink Floyd – Eclipse
  5. Pink Floyd – Brain Damage
Audioscrobbler/Last.fm

ClustrMap

Setting up SourceGear DiffMerge with Git

Posted in .NET | ALT.NET | Git at Wednesday, January 28, 2009 9:18 PM W. Europe Standard Time

Git Logo For about six month I’m using Git as my preferred Source Control Management system. That is, while my colleagues at work still work with Subversion and TortoiseSVN, I am leveraging the powers of Git behind the scenes. That is, I work on local (Git) feature branches that I commit to our SVN trunk every once in a while, typically after I finished working on a feature.

If you want to get started with Git, I recommend watching the GitCasts and try one of the Windows distributions, msysgit or Cygwin. (I switched to Cygwin after the msysgit team dropped SVN integration in their 1.6 release.)

Git heavily relies on the command line, and UI tools like gitk and TortoiseGit are not quite there yet. Using a CLI might be something a lot of Windows developers do not look forward to, but you still can configure support for some UI tools. For example, file diffs and merges can be customized to work with any tool (UI and CLI-based). I use SourceGear DiffMerge (free) as my primary diff and merge tool. It’s far better that what comes with TortoiseSVN or Git itself (again CLI-based).

I could only find sparse documentation on how to make DiffMerge work with Git, so I dove into the world of Shell programming and created a couple of simple scripts. Here is what I came up with.

diffmerge-diff.sh

#!/bin/sh

path="$(cygpath $1)"
old="$(cygpath --mixed --absolute "$2")"
new="$(cygpath --mixed --absolute "$5")"

#echo -e "path\n$path"
#echo -e "old\n$old"
#echo -e "new\n$new"

"/cygdrive/C/Tools/DiffMerge/diffmerge.exe" "$old" "$new" --title1="Old" --title2="New $path"

diffmerge-merge.sh

#!/bin/sh

localPath="$(cygpath --mixed --absolute "$2")"
basePath="$(cygpath --mixed --absolute "$1")"
remotePath="$(cygpath --mixed --absolute "$3")"
resultPath="$(cygpath --mixed --absolute "$4")"

if [ ! -f $basePath ]
then
    basePath="$(cygpath --mixed --absolute ~/diffmerge-empty)"
fi

#echo -ne "local\n$localPath\n"
#echo -ne "base\n$basePath\n"
#echo -ne "remote\n$remotePath\n"
#echo -ne "result\n$resultPath\n"

"/cygdrive/C/Tools/DiffMerge/diffmerge.exe" --merge --result="$resultPath" "$localPath" "$basePath" "$remotePath" --title1="Mine" --title2="Merged: $4" --title3="Theirs"

Setting up Git

  1. Put the files above in your home directory, either C:\Cygwin\home\<username> (Cygwin) or C:\Users\<username> (msysgit). Make sure the line endings are LF-only (UNIX style) and the file is saved without the UTF byte-order mark (BOM).
  2. Create an empty file named diffmerge-empty in the same directory.
  3. Modify the scripts to point to the correct location of DiffMerge (see the last lines). Some more modifications will be needed if you’re from the msysgit crowd, as the cygpath utility is not available there.
  4. Open a Git CLI and enter the following commands:
    git config --global merge.tool diffmerge
    git config --global mergetool.diffmerge.cmd "~/diffmerge-merge.sh \"\$BASE\" \"\$LOCAL\" \"\$REMOTE\" \"\$MERGED\""
    git config --global mergetool.diffmerge.trustExitCode false 
    git config --global diff.external "C:/Cygwin/home/<username>/diffmerge-diff.sh"
    This should add the following lines to your .gitconfig:
    [merge]
        tool = diffmerge
    [mergetool "diffmerge"]
        cmd = ~/diffmerge-merge.sh \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
        trustExitCode = false
    [diff]
        external = C:/Cygwin/home/<username>/diffmerge-diff.sh

Using DiffMerge

Using DiffMerge is pretty easy, the normal git diff and git mergetool commands work as usual, but will now spawn DiffMerge instead of vi (which is the default). If anything does not work as expected, uncomment the #echo lines and use a tool like Process Monitor and Process Explorer to see where things go wrong.

Happy diffing!

Monday, June 07, 2010 11:38:38 AM (W. Europe Daylight Time, UTC+02:00)
Hi Alex,

thanks for sharing the ~/diffmerge-empty trick. Saved my day.

Regards,
Steffen
All comments require the approval of the site owner before being displayed.
(will show your gravatar icon)
 
[Captcha]Enter the code shown (prevents robots):

Live Comment Preview