Monday, August 2, 2010

Merging Git with SourceGear DiffMerge



I develop in PHP and C#, switching between OSX (Native Bash) and Windows (Cygwin), so I try to make my solutions as DRY and cross-OS simple as possible. For a great solution for Cygwin checkout Alexander Grob post on the same issue, mine is a slight variation of Alex's.

$ nano ~/.bash_profile
DiffMerge_Path="/cygdrive/c/Program Files/SourceGear/DiffMerge"
if [ -d $DiffMerge_Path ]
then
    PATH="$DiffMerge_Path:$PATH"
fi

In order to make everything cross-OS, I add the DiffMerge binaries to the Path, above is an example on how to add it to Cygwin, adding it to the .bash_profile will ensure that it gets added automatically every time I log in.



So let's start at the beginning... understanding how git-mergetool command works, what a better place than the  git-mergetool fficial documentation (which is not always the best place, but a good one to start), and we also need to check DiffMerge Documentation in order to know how we should call it via the Command Line.

$ git config --global merge.tool diffmerge
$ git config --global mergetool.diffmerge.trustExitCode true
$ git config --global mergetool.keepBackup false
$ git config --global mergetool.diffmerge.cmd "diffmerge -nosplash
    -result=\"\$MERGED\" -title1=\"Ours\" -title2=\"Merged: \$MERGED\"
    -title3=\"Theirs\" \"\$LOCAL\" \"\$BASE\" \"\$REMOTE\""
$ git config -l

In the first line we assign a new tool for the git merge, and it's name will be diffmerge, it could be anything but diffmerge is an accurate name. The second line we specify that we will trust the code returned by the termination of the diffmerge window. Third line is a configuration property to remove any original file created by Git, if you want to keep it, just set it to true. Finally the most "complicated" line, this configuration value is the command that will be executed by git when calling the mergetool. The command is one huge line, but I broke it down in three for readability, according to diffmerge documentation we specify the parameters needed by the program. It's very important that you don't forget the backslashes, since they scape the quotes and dollar sign character. After you enter the configuration, you can verify it by typing git config -l, make sure that mergetool.diffmerge.cmd equals diffmerge -nosplash -reult="$MERGED" -title1="Ours" -title2="Merged: $MERGED" -title3="Theirs" "$LOCAL" "$BASE" "$REMOTE" , the $BASE, $LOCAL, $REMOTE and $MERGED variables will get replaced or injected with the corresponding file paths by Git, according to the Git MergeTool documentation.

And this is it, basically you just need to configure Git, so that it executes a command line that calls DiffMerge via the Command Line, after you fixed the errors, save the file and exit it. Below is a typical merging command line workout.

$ git checkout master
$ git merge the-branch
$ git mergetool