Git for Windows uses MSYS2 which is derived from Cygwin. While the location where "cygdrive" (Cygwin uses /cygdrive, MSYS2 uses /) gets mounted, differs by default, it can be brought into a form that is be compatible between both flavors which is prefixed /proc/cygdrive (using cygpath -U ...).
Why do I need this?
- while Cygwin features a
gitpackage, there is nogit-lfs. This led to quite some confusion initially, because theGit/cmd/git-lfsfrom Git for Windows was found and used by Cygwin, but turned out to be incompatible with thegitfrom Cygwin's package. Sure, I could build my owngit-lfs, but I don't want to. I want to leverage the Git for Windows installation that is already installed on our developers' systems. - Process creation on Windows in the Win32 subsystem is much more expensive than a
clone()orfork()on -- say -- Linux. Therefore I would like to avoid the complexity in my script to callcygpathacross all sorts of ofgitinvocations in one environment, but not the other ... so avoiding the spawning of additional processes is a real performance factor.
The problem
From the perspective of MSYS2 there is no Cygwin environment, so it gets to see the path for external tools, i.e. %ProgramFiles%\Git\cmd, hence C:\Program Files\Git\cmd\git.exe (or from Cygwin's perspective: /cygdrive/c/Program Files/Git/cmd/git).
This "flavor" of git expects the path in Windows respresentation, i.e. the form that cygwin -w or cygwin -m spit out.
Using "/cygdrive/c/Program Files/Git/cmd/git" --exec-path I am able to find the canonical path for Git for Windows' "exec directory":
$ cygpath -Ua "$("$(type -p git)" --exec-path)"
/proc/cygdrive/c/Program Files/Git/mingw64/libexec/git-core
Inquiring --exec-path again I can determine if this is the end of the indirection.
So, by using the following, I can populate a shell variable GITBIN with the absolute canonical path to git from Git for Windows, which ought to work in Cygwin and MSYS2 alike:
GITBIN="$(cygpath -Ua "$("$(type -p git)" --exec-path)")/git"
At this point I would expect that I can call $GITBIN using an absolute canonical path retrieved on the MSYS2 side using cygpath -Ua ....
Suppose the git repo I want to act on is checked out in /proc/cygdrive/x/gitrepo and Cygwin lets me change into that directory or list its contents.
Question
Why does the following fail?:
$ "$GITBIN" -C "/proc/cygdrive/x/gitrepo" status
fatal: cannot change to '/proc/cygdrive/x/gitrepo': No such file or directory
What I also tried
MSYS2 allows to use environment variables to control implicit path conversion. I have tried starting $GITBIN as follows:
env MSYS_NO_PATHCONV=1 "$GITBIN" -C /proc/cygdrive/x/gitrepo status
I also tried setting MSYS2_ARG_CONV_EXCL="-C" and I tried using --work-tree=/proc/cygdrive/x/gitrepo/.git instead of -C /proc/cygdrive/x/gitrepo in all permutations with these environment variables. But no luck ... the only difference was that the error message reads now fatal: not a git repository (or any of the parent directories): .git.
Then I even tried to coerce the $GITBIN into thinking it runs inside MSYS2 by setting environment variables, but admittedly I could be missing some:
env MINGW_CHOST=x86_64-w64-mingw32 MINGW_PREFIX=/mingw64 MSYSTEM_CARCH=x86_64 MSYSTEM_CHOST=x86_64-w64-mingw32 MSYSTEM_PREFIX=/mingw64 MSYSTEM=MINGW64 "$GITBIN" -C /proc/cygdrive/x/gitrepo status
Nothing seems to convince MSYS2 from the outside to consider the passed path already to be suitable for it and only internally convert it.
So far the only workaround I have found is to use the representation that
cygpath -mreturns across MSYS2 and Cygwin. I.e. basically Windows paths with a drive letter, but forward slashes instead of backslashes, e.g.X:/gitrepofor/proc/cygdrive/x/gitrepofrom the question.This seems to be more "portable" even than the representation that
cygpath -Uareturns.But this was all deduced from observation of the behavior and not from looking at the code.
NB: If there is someone who can 1) at least explain why the MSYS2-
git.exerefuses the provided path and 2a) provide a working alternative withcygpath -Uaor 2b) provide authoritative sources that confirm thatcygpath -mshould be used across the board, I shall accept and upvote that answer.