On Thu, Nov 02, 2017 at 11:45:55PM +0000, Andrew Baumann wrote: > I have a workaround for this, but someone on stack overflow [1] > suggested reporting it upstream, so here you go: > > I have a fancy shell prompt that executes "git rev-parse > --is-inside-work-tree" to determine whether we're currently inside a > working directory. This causes git to walk up the directory hierarchy > looking for a containing git repo. For example, when invoked from my > home directory, it stats the following paths, in order: > > /home/me/.git > /home/me/.git/HEAD > /home/me/HEAD > /home > /home/.git > /home/.git/HEAD > /home/HEAD > / > /.git > /.git/HEAD > //HEAD > > The last name (//HEAD) interacts badly with Cygwin, which interprets > it as a UNC file share, and so demand-loads a bunch of extra DLLs and > attempts to resolve/contact the server named HEAD. This obviously > doesn't work too well, especially over a slow network link. > > I've tested with the latest Cygwin git (2.15.0); this was also present > in a prior version. Interesting. I can reproduce on Linux (but of course "//HEAD" is cheap to look at there). It bisects to ce9b8aab5d (setup_git_directory_1(): avoid changing global state, 2017-03-13). Before that, the end of the strace for "git rev-parse --git-dir" looks like: chdir("..") = 0 stat(".git", 0x7fffba398e00) = -1 ENOENT (No such file or directory) lstat(".git/HEAD", 0x7fffba398dd0) = -1 ENOENT (No such file or directory) lstat("./HEAD", 0x7fffba398dd0) = -1 ENOENT (No such file or directory) write(2, "fatal: Not a git repository (or "..., 69) = 69 and after: stat("/.git", 0x7ffdb28b7eb0) = -1 ENOENT (No such file or directory) lstat("/.git/HEAD", 0x7ffdb28b7e80) = -1 ENOENT (No such file or directory) lstat("//HEAD", 0x7ffdb28b7e80) = -1 ENOENT (No such file or directory) write(2, "fatal: Not a git repository (or "..., 69) = 69 Switching to using absolute paths rather than chdir-ing around is intentional for that commit, but it looks like we just need to special-case the construction of the root path. Like this, perhaps: diff --git a/setup.c b/setup.c index 27a31de33f..5d0b6a88e3 100644 --- a/setup.c +++ b/setup.c @@ -283,7 +283,9 @@ int is_git_directory(const char *suspect) size_t len; /* Check worktree-related signatures */ - strbuf_addf(&path, "%s/HEAD", suspect); + strbuf_addstr(&path, suspect); + strbuf_complete(&path, '/'); + strbuf_addstr(&path, "HEAD"); if (validate_headref(path.buf)) goto done; -Peff