Roy Lindauer

Multi-Platform Git Diff and Merge Tools

Maintain a single .gitconfig between different operating systems by using proxy scripts for git diff and git merge tools.

We first need to know which operating system we are using. I do this by by extracting the value from uname and then setting the value to an environtment variable.

On MacOS this will return darwin, on most Linux distributions it should return linux.

export DOTFILES_OS=`uname | awk '{print tolower($0)}'`

In your .gitconfig you would would typically define difftool and mergetool to whatever tools you have installed on your local system. If you are like me though you use your favorite tools for the system you are working on, and often those are going to be different. For example, I use meld on Linux and Kaleidescope on MacOS.

What we are going to do instead is to configure difftool and mergetool to reference a custom bash script that will act as proxy. Here's the relevant parts of my .gitconfig

[difftool]
    prompt = false
[difftool "git-diff-tool"]
    cmd = git-diff-tool "$LOCAL" "$REMOTE" "$MERGED"
[diff]
    tool = git-diff-tool

[mergetool]
    keepBackup = false
    prompt = false
[mergetool "git-merge-tool"]
    cmd = git-merge-tool "$LOCAL" "$BASE" "$REMOTE" "$MERGED"
    trustExitCode = true
[merge]
    tool = git-merge-tool

Now on to the custom proxy scripts.

git-diff-tool

#!/usr/bin/env bash

LOCAL="$1"
REMOTE="$2"
MERGED="$3"

if [ $DOTFILES_OS == 'darwin' ]; then
  ksdiff --partial-changeset --relative-path "$MERGED" -- "$LOCAL" "$REMOTE"
fi

if [ $DOTFILES_OS == 'linux' ]; then
  meld \"$LOCAL\" \"$REMOTE\"
fi

git-merge-tool

#!/usr/bin/env bash

LOCAL=$1
BASE=$2
REMOTE=$3
MERGED=$4

if [ $DOTFILES_OS == 'darwin' ]; then
  ksdiff --merge --output "$MERGED" --base "$BASE" -- "$LOCAL" --snapshot "$REMOTE" --snapshot
fi

if [ $DOTFILES_OS == 'linux' ]; then
  meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"
fi

Ensure these scripts are executable and that they in your $PATH

I think this is a neat solution to working across multiple workstations while maintaining a single gitconfig.