SourceTree external diff path issue on Windows
Asked by Paul Lotz:

I attempted to configure SourceTree on Windows 8.1 to use an external diff tool (LVCompare).

In SourceTree on the Tools.Options...Diff page I set the External Diff Tool to \<Custom\> and set

DiffCommand = C:\\Program Files (x86)\\National Instruments\\Shared\\LabVIEW Compare\\LVCompare.exe

and

Arguments = $LOCAL $REMOTE.

When I right-click on a file in SourceTree and invoke External Diff, the following dialog appears:

![](../../upfiles/DiffError.PNG)

The good news is that we are invoking the LabVIEW Compare application (yay!), but the path is malformed. (In particular, there is a backward-forward slash combination.)

How can I resolve this?

Paul


Answers:
author: Paul Lotz
body: Atlassian support and Git support have both pointed out that local and remote are consistent with the definition in the manual for difftool [](http://git-scm.com/docs/git-difftool.html)<http://git-scm.com/docs/git-difftool.html>.

So, what we have is, in the global .gitconfig file:  
\[diff\]  
tool = "sourcetree"  
\[difftool "sourcetree"\]

cmd = ''C:/Users/Paul/AppData/Local/Programs/Git/bin/_LVCompareWrapper.sh'' \\"$REMOTE\\" \\"$LOCAL\\"

The associated wrapper script contents are:

#!/bin/bash

# Method to determine absolute path  
# The -W parameter on the pwd command is necessary to return the Windows version of the path.  
# Not using the -W parameter will result in a conversion of temp directory to a 'tmp' path meaningful only in the Linux # environment.  
# Piping the result through tr '/' '\\\\' translates the forward slashes to backslashes.  
# Windows understands forward slashes, but LVCompare.exe does not.

abspath () {  
(  
DIR=$(dirname "$1")  
FN=$(basename "$1")  
cd "$DIR"  
printf "%s/%s" "$(pwd -W)" "$FN" \| tr '/' '\\\\'  
)  
}

lvcompare="C:\\Program Files (x86)\\National Instruments\\Shared\\LabVIEW Compare\\LVCompare.exe"  
local=$(abspath "$1")

comments: author: MikeD
body: For anyone who may be trying to get this to work, you'll notice that the bottom of this script is cut off. I have included my script below. Note that it is for IntelliJ, which also requires the first argument to be the action that is being taken, which in this case is "diff".#!/bin/bash# Method to determine absolute path# The -W parameter on the pwd command is necessary to return the Windows version of the path.# Not using the -W parameter will result in a conversion of temp directory to a 'tmp' path meaningful only in the Linux # environment.# Piping the result through tr '/' '\\\\' translates the forward slashes to backslashes.abspath () { ( DIR=$(dirname "$1") FN=$(basename "$1") cd "$DIR" printf "%s/%s" "$(pwd -W)" "$FN" \| tr '/' '\\\\' )}intellij="C:\\\\Program Files (x86)\\\\JetBrains\\\\IntelliJ IDEA 14.1\\\\bin\\\\idea64.exe"local=$(abspath "$2")remote=$(abspath "$3")exec "$intellij" "$1" "$local" "$remote"


author: MikeD
body: To do the same thing but allow it to handle both diff and merge commands, use the following:#!/bin/bash# Method to determine absolute path# The -W parameter on the pwd command is necessary to return the Windows version of the path.# Not using the -W parameter will result in a conversion of temp directory to a 'tmp' path meaningful only in the Linux # environment.# Piping the result through tr '/' '\\\\' translates the forward slashes to backslashes.abspath () { ( DIR=$(dirname "$1") FN=$(basename "$1") cd "$DIR" printf "%s/%s" "$(pwd -W)" "$FN" \| tr '/' '\\\\' )}intellij="C:\\\\Program Files (x86)\\\\JetBrains\\\\IntelliJ IDEA 14.1\\\\bin\\\\idea64.exe"local=$(abspath "$2")remote=$(abspath "$3")base=""merged=""if \[ ! -z "$4" \]; then base=$(abspath "$4");fi;if \[ ! -z "$5" \]; then merged=$(abspath "$5");fi;exec "$intellij" "$1" "$local" "$remote" "$base" "$merged"


author: Javier Jose Lopez Bohorquez
body: En mi caso cambie la direcci?n donde apuntan los archivos compare.exe y merge.exe. ya que mi sistema es de 64 bits y se encontraba en "Archivo de programas" y no en "Archivos de programa (x86)" modificando esta ruta para ambos archivos me funcion? perfectamente.

ejemplo:

lvcompare="C:\\Program Files (x86)\\National Instruments\\Shared\\LabVIEW Compare\\LVCompare.exe"

por:

lvcompare="C:\\Program Files\\National Instruments\\Shared\\LabVIEW Compare\\LVCompare.exe"

comments: author: Javier Jose Lopez Bohorquez
body: twitter@javierlopezb


author: Paul Lotz
body: I tested using single backslashes in the path to the LVCompare program and this worked fine.

Diff with new file: The git difftool command only allows differencing on files that have changed, so I don't think we need to worry about that.

Calling External Diff from SourceTree on, say, a .lvproj file, will result in an error from LVCompare, since it cannot compare files of this type. I'm not sure what I would do in the script in that case. I think the client or Git itself would be the better places to address this.


author: Paul Lotz
body: I have only tested it under Windows 8.1. :-)

Good catch on the single backslash. My guess is the path to the LVCompare program will work with single or double slashes, or even forward slashes. I will have to try this, but I can't just at the moment.


author: Niels G?ran Blume
body: Hey,

yeah, but still.. I would like the idea.. (What almost works for me is just having TortoiseGit installed and it seems to pick up the .git folder and bases the icons on that..

@Paul Lotz:

- SOLVED: Have you tested this under Windows 8.1? Under Windows 7 it works for me, Windows 8.1 not so much.. (still doing debugging..)

Problem was in front of the PC trying to do a diff with a new file... Works fine...   
(Might be something to catch in future revisions of the Wrapper Script ;-) )

- Looking at the script you posted, I noticed that one time there is only a single backslash:

lvcompare="C:\\\\Program Files (x86)\\National Instruments\\\\Shared\\\\LabVIEW Compare\\\\LVCompare.exe"

Intended oder parsing error ?

Best regards

Niels G?ran


author: Seth
body: Seeing as SourceTree doesn't integrate with Explorer at all (as opposed to Tortoise, which is almost exclusively integrated with Explorer), I expect the icon-overlay will never happen.


author: Niels G?ran Blume
body: Dear Paul,

works like a charm !

I've seen a by-file-extension-diff in TortoiseGit, bt that is probably handle before Git as well...

The By-file-extension-diff and somekind of icon-overlay for file status (like TortoiseZZZ) are the two main things missing from Source Tree in my opinion.

Best regards

Niels G?ran


author: Paul Lotz
body: No, I set the SourceTree Diff options to:

External Diff Tool: Custom

Diff Command: 'C:/Users/Paul/AppData/Local/Programs/Git/bin/_LVCompareWrapper.sh'

Arguments: \\"$REMOTE\\" \\"$LOCAL\\"

Setting these options updates the global .gitconfig file.

It is possible to update the .gitconfig file manually, of course.

I haven't attempted to set up a merge yet. I expect to return to that when I have a chance.

Git Diff does not support file-extension-based tool selection, as Subversion does. (That seems to me to be an obvious shortcoming on Git's part, but I'm not sure it's all that important in practice.) You could presumably place code to handle tool selection inside the shell script. I haven't tried that.


author: Niels G?ran Blume
body: Sounds great that you have a working solution..

I'm about to test it out..

One question ahead of trial and error:

You set the Source Tree Diff (and Merge) settings to "System Default". Correct ?

Thanks !

How could that be expanded to handle for example ".txt"-files with the regular Kdiff3 or programs alike ? \[A file extension based diff command would be great, if not possible yet\]

Best regards

Niels G?ran


author: Paul Lotz
body: Success!

OK, it seems this is a problem with MSys or MSysGit mangling the Windows paths. Our local Git guru, with background input from Git support and my tests, helped me write a shell script to do two things:  
1) Return the Windows absolute paths.  
2) Convert the forward slashes to back slashes.  

Here are the details on _LVCompareWrapper.sh:  
File location: On my machine, this file is in the C:\\Users\\Paul\\AppData\\Local\\Programs\\Git\\bin directory.  

The actual filename does not matter, as long as the configuration item in the .gitconfig file points to it.  

The file contents are presently:  

#!/bin/bash  

# Method to determine absolute path  
# The -W parameter on the pwd command is necessary to return the Windows version of the path.  
# Not using the -W parameter will result in a conversion of temp directory to a 'tmp' path meaningful only in the Linux #  

environment.  
# Piping the result through tr '/' '\\\\' translates the forward slashes to backslashes.  
# Windows understands forward slashes, but LVCompare.exe does not.  

abspath () {  
(  
DIR=$(dirname "$1")  
FN=$(basename "$1")  
cd "$DIR"  
printf "%s/%s" "$(pwd -W)" "$FN" \| tr '/' '\\\\'  
)  
}  

lvcompare="C:\\\\Program Files (x86)\\National Instruments\\\\Shared\\\\LabVIEW Compare\\\\LVCompare.exe"  
local=$(abspath "$1")  
remote=$(abspath "$2")  
exec "$lvcompare" -nobdpos -nofppos "$local" "$remote"  
# For the options, see [](http://zone.ni.com/reference/en-XX/help/371361H-01/lvhowto/configlvcomp_thirdparty/ "External link")<http://zone.ni.com/r...mp_thirdparty/>.  

Of course we need to modify the global .gitconfig file, too. Here are the details:  

This is the global .gitconfig file. On my machine this resides in the C:\\Users\\Paul directory.  

The relevant part of the file (set up to work with SourceTree, but it is possible to use another tool or to use the wrapper tool via the git difftool command) presently is:  

\[diff\]  
tool = "sourcetree"  
\[difftool "sourcetree"\]  
cmd = ''C:/Users/Paul/AppData/Local/Programs/Git/bin/_LVCompareWrapper.sh'' \\"$REMOTE\\" \\"$LOCAL\\"  
# Note that the parameters are actually passed in reverse order to the wrapper.


author: Paul Lotz
body: The parameter reversal does seem to me to be a bug in Git.


author: Ricardo Schmidt
body: The VI in comparision should be placed inside project directory, side by side with original but with other name, could be \<name-of-the-vi\>_\<commit-id\>.vi. If its in other directory it may work too, but its not the correct way.   
For instance I am using [](https://github.com/joerg/LabViewGitEnv%20)<https://github.com/joerg/LabViewGitEnv>and using the command line to perform merge and compare.

comments: author: Niels G?ran Blume
body: Hey everyone,

just to chime in here real quick...

Before finding this thread, I asked a similar question here (<https://answers.atlassian.com/questions/261797/combining-source-tree-and-tortoise-git#>).

I don't think it is a problem with Git, it appears to be related to the way Source Tree creates the second file to diff with. Instead of creating it in the original directory, it is creating the file as a temporary file in the temp folder somewhere on your harddrive.

Using TortoiseGit and adding an entry for ".vi" files with the following syntax works exactly the way diff needs to work with LabVIEW:

"C:\\Program Files (x86)\\National Instruments\\Shared\\LabVIEW Compare\\LVCompare.exe" %mine %base -nobdcosm -nobdpos

@Ricardo: I tried to install the LabViewGitEnv, but didn't succeed..

I failed at this step: "In gitk select Edit -\> Options and choose the according LVGitKExternalDiffWrapper" I'm not sure, which is the according wrapper..

Any help would be appreciated..

Kind regards

Niels G?ran


author: Paul Lotz
body: Sorry for the late reply. I apparently wasn't set up to follow the discussion, but I am now.

I opened a support case (**STSP-956)**with Atlassian. The long and short of it is that Atlassian thinks the problem is in Git. I have successfully called LVCompare a basic command line\* giving it to files (not under source control) but I have to figure out how to do this using Git itself (or demonstrate that it fails). I'm not sure yet if is essentially a bug/incompatibility in Git or if there is some syntax trick I have to find. I plan to work on this now, and will report back if I learn something.

__

\* Details:

For a test, I created a new LabVIEW project with two VIs, one named 'remote.vi', and another 'local.vi', in a 'LVCompareTest' directory. I then executed the following command in a Windows Command Prompt window:

C:\\Users\\Paul\>"C:\\Program Files (x86)\\National Instruments\\Shared\\LabVIEW Compar

e\\LVCompare.exe" C:\\LVCompareTest\\local.vi C:\\LVCompareTest\\remote.vi

___


author: Ricardo Schmidt
body: Same problem here in Windows 7.

![](../../../upfiles/compareerror_2.png)

Also when trying to compare VIs containing white spaces in the name (common in LabVIEW) it gives this error:

![](../../../upfiles/compareerror_1.png)

I found out that if I set Arguments to \\"$LOCAL\\" \\"$REMOTE\\" it makes the error gets like the one posted here.

comments: author: Niels G?ran Blume
body: Hey,

any luck figuring this out?

I'm stuck with the same problem, and it appears to be related to the fact, that Source tree is using relative paths, but LVCompare needs absolute path.

Furthermore both versions of the VI (especially the temporary version) have to be in the correct location (with the original VI), since otherwise it is not possible for LabVIEW to show or find Sub-VIs.

Kind regards

Niels G?ran


author: Paul Lotz
body: For the record, there are examples of configuring other external diff tools to work on Windows, e.g.,

[](http://www.scootersoftware.com/support.php?zz=kb_vcs)<http://www.scootersoftware.com/support.php?zz=kb_vcs>(GIT FOR WINDOWS section)  
[](http://cuppster.com/2011/02/08/how-to-setup-gits-difftool-on-windows/)<http://cuppster.com/2011/02/08/how-to-setup-gits-difftool-on-windows/>  
[](http://davesquared.net/2010/03/easier-way-to-set-up-diff-and-merge.html)<http://davesquared.net/2010/03/easier-way-to-set-up-diff-and-merge.html>  
[](http://stackoverflow.com/questions/7944757/configuring-a-diff-tool-for-git-on-windows)<http://stackoverflow.com/questions/7944757/configuring-a-diff-tool-for-git-on-windows>

and the relevant Git command is:

[](http://git-scm.com/docs/git-difftool.html)<http://git-scm.com/docs/git-difftool.html>

(This doesn't resolve the issue, but hopefully it is useful background information.)


author: Paul Lotz
body: Sorry for the late reply. I apparently wasn't set up to follow the discussion, but I am now.

I opened a support case (**STSP-956)**with Atlassian. The long and short of it is that Atlassian thinks the problem is in Git. I have successfully called LVCompare using a basic command line call\* passing it paths to files (not under source control) but I have to figure out how to do this using Git itself (or demonstrate that it fails). I'm not sure yet if is essentially a bug/incompatibility in Git or if there is some syntax trick I have to find. I plan to work on this now, and will report back if I learn something.

__

\* Details:

For a test, I created a new LabVIEW project with two VIs, one named 'remote.vi', and another 'local.vi', in a 'LVCompareTest' directory. I then executed the following command in a Windows Command Prompt window:

C:\\Users\\Paul\>"C:\\Program Files (x86)\\National Instruments\\Shared\\LabVIEW Compar

e\\LVCompare.exe" C:\\LVCompareTest\\local.vi C:\\LVCompareTest\\remote.vi

___


author: Paul Lotz
body: Well, I succeeded in doing the same call using the difftool command from the Git Bash window command line, and the result was the same (same error dialog with the same malformed path).

(I just typed difftool and clicked 'y' to compare a .vi file when prompted.)

The relevant contents of the .gitconfig file are now:

\[diff\]

tool = "LVCompare"

\[difftool "LVCompare"\]

cmd = 'C:/Program Files (x86)/National Instruments/Shared/LabVIEW Compare/LVCompare.exe' $LOCAL $REMOTE


author: Paul Lotz
body: Since I get the same results with Git, I contacted the folks associated with Git to see if they know....

I did more web searches and found references to using a backslash (\\) as an escape key, basically, but I haven't found a combination that works. Presently the .gitconfig file looks has this text:

\[diff\]

tool = "LVCompare"

\[difftool "LVCompare"\]

cmd = 'C:/Program Files (x86)/National Instruments/Shared/LabVIEW Compare/LVCompare.exe' \\"$LOCAL\\" \\"$REMOTE\\"

The result (bad remote path) is the same.


author: KieranA
body: Hey Paul,

If this were the case, then wouldn't it need to look like this?

```
cmd = 'C:/Program\ Files\ (x86)/National\ Instruments/Shared/LabVIEW\ Compare/LVCompare.exe' \"$LOCAL\" \"$REMOTE\"
```

Cheers


author: Paul Lotz
body: Short answer: No. I'm not sure I understand what you are trying to say, though.

In any event, the problem is not in the path to the LVCompare.exe. This part of the task works! The issue is with the paths passed as parameters to LVCompare.exe (at least with the remote path).

Paul


Tags: diff

external

moderators

path

windows