git diff tmp file invalid on windows when using external program on Windows 7
Asked Answered
R

3

3

I'm following the docs from the Git configuration page and trying to apply this to my Windows 7 environment. When I run say, "git diff file0" I get an error in P4Merge:

Errors: '/tmp/cH9ccM_file0' is (or points to) an invalid file.

This is a true statement. I do not have a directory called "/tmp". I've checked in C:\tmp, C:\cygwin\tmp, and %PROGRAMFILES%\Git\tmp.

Any ideas on how to change this directory to something I do have?

EDIT:

Additional info. Ultimately, I'm trying to get WinMerge (or any external program) to work. I chose to use P4Merge earlier, because I couldn't get WinMerge to work, so I decided to go with the program that was used in the aforementioned article.

Below is the relevant part of my .gitconfig:

[merge]
tool = extMerge
[mergetool "extMerge"]
cmd = extMerge \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
trustExitCode = false
[diff]
external = extDiff

extDiff script:

#!/usr/bin/sh
# extDiff
# Wrapper for using an external diff tool in Git
echo "File 1: $2"
echo "File 2: $5"
/usr/local/bin/extMerge "$2" "$5"

extMerge script:

#!/usr/bin/sh
echo $*
/c/Program\ Files\ \(x86\)/WinMerge/WinMergeU.exe $*

So if I change a file called index.html, and run git diff, this is the result:

File 1: /tmp/XfGpOC_index.html
File 2: index.html
Russ answered 14/5, 2013 at 19:26 Comment(0)
P
8

I assume you're using Cygwin... I think the problem is that for Cygwin, /tmp exists, but for Windows, it doesn't (it's somewhere else). For me, Cygwin's /tmp is located in $HOME/AppData/cygwin/tmp and that's where the file was. This might be different depending on how you installed Cygwin. Once you find Cygwin's /tmp, it's just a matter of finding a good environment variable (or creating a new one, if you need) to get a Windows path to the temp file. This worked for me:

[diff]
   tool = p4mergeTool
[difftool "p4mergeTool"]
   cmd = p4merge.exe $HOMEPATH/AppData/cygwin$LOCAL $REMOTE

I used HOMEPATH instead of HOME, because (it appears) HOMEPATH is the Windows HOME environment variable (\Users\myusername), while HOME is the cygwin HOME environment variable (/cygdrive/c/Users/myusername). From Cygwin, type printenv to see which environment variables might be a good fit.

Phallus answered 11/12, 2013 at 3:58 Comment(3)
Finally. This answer made my day!Anjaanjali
Sorry, but it's error prone and inflexible. It won't handle both absolute and relative paths correctly, while Git uses both. In the end of the day it would become a source of really awful problems, even if it seems to work fine at first.Acknowledge
FYI, the cygwin path I end up with was c:/tools/cygwin/tmp in this environment: (Windows 2012 R2 Server Standard Ver 6.3 Build 9600, cygwin DLL version 2.0.4)Heddy
A
12

The correct solution would be using Cygwin's cygpath tool to convert path formats:

[difftool "p4merge"]
    cmd = p4merge \"$(cygpath -w \"$LOCAL\")\" \"$(cygpath -w \"$REMOTE\")\"

The same goes for mergetool:

[mergetool "p4merge"]
    keepBackup = false
    trustExitCode = true
    cmd = p4merge \"$(cygpath -w \"$BASE\")\" \"$(cygpath -w \"$LOCAL\")\" \"$(cygpath -w \"$REMOTE\")\" \"$(cygpath -w \"$MERGED\")\"

Please note that this solution (as well as the question, actually) applies only to Cygwin environment. I've never had Git Bash exhibit the same problem and don't know if it has a utility similar tocygpath.

UPDATE: Unfortunately, the cygpath utility does a poor job converting /dev/null to its Windows equivalent. It will return the invalid \\.\NUL path, and so diffing new files will fail. I'll issue another update with the workaround, as soon as I find it.

Acknowledge answered 10/10, 2014 at 10:31 Comment(0)
P
8

I assume you're using Cygwin... I think the problem is that for Cygwin, /tmp exists, but for Windows, it doesn't (it's somewhere else). For me, Cygwin's /tmp is located in $HOME/AppData/cygwin/tmp and that's where the file was. This might be different depending on how you installed Cygwin. Once you find Cygwin's /tmp, it's just a matter of finding a good environment variable (or creating a new one, if you need) to get a Windows path to the temp file. This worked for me:

[diff]
   tool = p4mergeTool
[difftool "p4mergeTool"]
   cmd = p4merge.exe $HOMEPATH/AppData/cygwin$LOCAL $REMOTE

I used HOMEPATH instead of HOME, because (it appears) HOMEPATH is the Windows HOME environment variable (\Users\myusername), while HOME is the cygwin HOME environment variable (/cygdrive/c/Users/myusername). From Cygwin, type printenv to see which environment variables might be a good fit.

Phallus answered 11/12, 2013 at 3:58 Comment(3)
Finally. This answer made my day!Anjaanjali
Sorry, but it's error prone and inflexible. It won't handle both absolute and relative paths correctly, while Git uses both. In the end of the day it would become a source of really awful problems, even if it seems to work fine at first.Acknowledge
FYI, the cygwin path I end up with was c:/tools/cygwin/tmp in this environment: (Windows 2012 R2 Server Standard Ver 6.3 Build 9600, cygwin DLL version 2.0.4)Heddy
R
0

Looks like a mistake in your gitconfig. Have you seen this Stackoverflow question?

I blogged about setting up P4Merge ages ago before git started supporting it directly but it still works if you are stuck: http://danlimerick.wordpress.com/2011/06/19/git-for-window-tip-use-p4merge-as-mergetool/

EDIT: To be more explicit, it is the escaping that is your problem. In my .gitconfig file for P4Merge it looks like this:

cmd = p4merge.exe /\"$BASE/\" /\"$LOCAL/\" /\"$REMOTE/\" /\"$MERGED/\"

So try this:

cmd = extMerge /\"$BASE/\" /\"$LOCAL/\" /\"$REMOTE/\" /\"$MERGED/\"

There is a difference with escaping if you set it from the command line or make the change directly in your .gitconfig file.

Roaster answered 14/5, 2013 at 21:13 Comment(1)
It's not about escaping, but paths. For example, Git with Cygwin passes /tmp/... as a parameter to P4Merge. However, such a path is not valid in a Windows environment, and since P4Merge is not a Cygwin application, it is not aware of the path format not being correct. As it tries to request the file from the system, it finds that the file (path) does not exist.Acknowledge

© 2022 - 2024 — McMap. All rights reserved.