Configuring multiple external diff tools based on extension?
Asked by IBrown_BluePrint:

I have multiple different binary filetypes that require different programs to diff and merge. I would like to be able to launch the proper diff program when right-clicking a file and selecting \`External Diff\`.

I already have all the different difftools and mergetools setup in my global config like so:

\~\~\~

# Differencing Configuration  
\[diff\]  
tool = WinMerge  
\[difftool "WinMerge"\]  
cmd = \\"C:\\\\Program Files\\\\WinMerge\\\\WinMergeU.exe\\" -e -u -dl \\"Old $BASE\\" -dr \\"New $BASE\\" \\"$LOCAL\\" \\"$REMOTE\\"  
trustExitCode = true  
\[difftool "sourcetree"\]  
cmd = '' \\"$LOCAL\\" \\"$REMOTE\\"  
\[difftool "LogixCompare"\]  
cmd = \\"C:\\\\Program Files (x86)\\\\Rockwell Software\\\\Logix Designer Tools\\\\Logix Designer Compare Tool\\\\RSLCompare.exe\\" \\"$LOCAL\\" \\"$REMOTE\\" -PM FastestCompare

\~\~\~

I also setup the extensions in gitattributes like \`\*.acd binary diff=LogixCompare\`, but doing an external diff on such a file still just opens WinMerge (my default difftool as shown above).

EDIT: I now know that gitattributes only launches a diff driver which is different from a difftool. I guess the best I can hope for is a new feature in SourceTree that would allow us to select one of the configured difftools as an "advanced" External Diff. \`git difftool --tool-help\` will list the available built-in and user configured tools, so maybe SourceTree can use that to populate the list or directly read them from the global config file?


Answers:
author: Mike Corsaro
body: Hello! Sourcetree doesn't currently support this feature, but we appreciate the suggestion!

However, that doesn't mean it's impossible to accomplish this. You can use the "Custom Difftool" setting to point to a script you've created to allow custom diff tools to launch depending on the file type. [You can find the logic for this idea here.](https://staxmanade.com/2014/12/use-different-git-diff-tools-per-file-extension/) Just be sure to configure ST to point to that script.


author: IBrown_BluePrint
body: I had to do some playing around to actually get the path formatting and everything to work on Windows. This is my difftool entry:

```
[difftool "ExtSelector"]
cmd = \"C:\\Program Files\\Git\\ExtensionSelect_DiffTool.sh\" \"$MERGED\" \"$BASE\" \"$LOCAL\" \"$REMOTE\"
```

And this is the contents of that script that finally didn't complain about paths and succeeded every time:

```
?#!/bin/bash

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

EXTENSION=${1##*.}

shopt -s nocasematch
case "${EXTENSION,,}" in
acd)
C:/Program\ Files\ \(x86\)/Rockwell\ Software/Logix\ Designer\ Tools/Logix\ Designer\ Compare\ Tool/RSLCompare.exe $LOCAL $REMOTE -PM FastestCompare
;;
*)
C:/Program\ Files/WinMerge/WinMergeU.exe -e -u -dl Local -dm Base -dr Remote $LOCAL $BASE $REMOTE -o $MERGED
;;
esac

exit $?
```

Note that I pass the file path variables already quoted, so they are unquoted when used in the script. I went ahead and passed all three file versions to Winmerge, so most would probably pair that down to just Local and Remote.

comments: author: Mike Corsaro
body: Nice work! Thanks for sharing your solution!


author: gilgen-zt
body: Hi  
Is this feature (use external diff tools based on extension) meanwhile implemented in Sourcetree?

I made following entry in the gitconfig

```
[difftool "vw7diff"]
cmd = 'C:/Program Files (x86)/INOSOFT GmbH/VisiWin 7/Development/bin/VisiWin7.ProjectCompare.exe' -c \"$LOCAL\" \"$REMOTE\"
```

And added following in the gitattributes

```
*.vw7 diff=vw7diff
```

But when I rightclick on the .vw7 file in sourcetree to start the external diff nothing happens.

When I enter following command in git bash it works. So is there any fault in the entry in my gitattributes?

```
git difftool -t vw7diff -y -- HMI/HmiServer/HmiServer.vw7?
```

comments: author: IBrown_BluePrint
body: gitattributes doesn't let you set the difftool for different filetypes (it should and I've made that request with the git team). You have to setup your difftool to be a script like I did in my follow-up post in this thread.


Tags: diff