Browse Source
A regression for cygwin users was introduced with commit 05b458c
,
"real_path: resolve symlinks by hand".
In the the commit message we read:
The current implementation of real_path uses chdir() in order to resolve
symlinks. Unfortunately this isn't thread-safe as chdir() affects a
process as a whole...
The old (and non-thread-save) OS calls chdir()/pwd() had been
replaced by a string operation.
The cygwin layer "knows" that "C:\cygwin" is an absolute path,
but the new string operation does not.
"git clone <url> C:\cygwin\home\USER\repo" fails like this:
fatal: Invalid path '/home/USER/repo/C:\cygwin\home\USER\repo'
The solution is to implement has_dos_drive_prefix(), skip_dos_drive_prefix()
is_dir_sep(), offset_1st_component() and convert_slashes() for cygwin
in the same way as it is done in 'Git for Windows' in compat/mingw.[ch]
Extract the needed code into compat/win32/path-utils.[ch] and use it
for cygwin as well.
Reported-by: Steven Penny <svnpenn@gmail.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Torsten Bögershausen <tboegi@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Torsten Bögershausen
6 years ago
committed by
Junio C Hamano
9 changed files with 54 additions and 72 deletions
@ -1,19 +0,0 @@
@@ -1,19 +0,0 @@
|
||||
#include "../git-compat-util.h" |
||||
#include "../cache.h" |
||||
|
||||
int cygwin_offset_1st_component(const char *path) |
||||
{ |
||||
const char *pos = path; |
||||
/* unc paths */ |
||||
if (is_dir_sep(pos[0]) && is_dir_sep(pos[1])) { |
||||
/* skip server name */ |
||||
pos = strchr(pos + 2, '/'); |
||||
if (!pos) |
||||
return 0; /* Error: malformed unc path */ |
||||
|
||||
do { |
||||
pos++; |
||||
} while (*pos && pos[0] != '/'); |
||||
} |
||||
return pos + is_dir_sep(*pos) - path; |
||||
} |
@ -1,2 +0,0 @@
@@ -1,2 +0,0 @@
|
||||
int cygwin_offset_1st_component(const char *path); |
||||
#define offset_1st_component cygwin_offset_1st_component |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
#include "../../git-compat-util.h" |
||||
|
||||
int win32_skip_dos_drive_prefix(char **path) |
||||
{ |
||||
int ret = has_dos_drive_prefix(*path); |
||||
*path += ret; |
||||
return ret; |
||||
} |
||||
|
||||
int win32_offset_1st_component(const char *path) |
||||
{ |
||||
char *pos = (char *)path; |
||||
|
||||
/* unc paths */ |
||||
if (!skip_dos_drive_prefix(&pos) && |
||||
is_dir_sep(pos[0]) && is_dir_sep(pos[1])) { |
||||
/* skip server name */ |
||||
pos = strpbrk(pos + 2, "\\/"); |
||||
if (!pos) |
||||
return 0; /* Error: malformed unc path */ |
||||
|
||||
do { |
||||
pos++; |
||||
} while (*pos && !is_dir_sep(*pos)); |
||||
} |
||||
|
||||
return pos + is_dir_sep(*pos) - path; |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
#define has_dos_drive_prefix(path) \ |
||||
(isalpha(*(path)) && (path)[1] == ':' ? 2 : 0) |
||||
int win32_skip_dos_drive_prefix(char **path); |
||||
#define skip_dos_drive_prefix win32_skip_dos_drive_prefix |
||||
static inline int win32_is_dir_sep(int c) |
||||
{ |
||||
return c == '/' || c == '\\'; |
||||
} |
||||
#define is_dir_sep win32_is_dir_sep |
||||
static inline char *win32_find_last_dir_sep(const char *path) |
||||
{ |
||||
char *ret = NULL; |
||||
for (; *path; ++path) |
||||
if (is_dir_sep(*path)) |
||||
ret = (char *)path; |
||||
return ret; |
||||
} |
||||
#define find_last_dir_sep win32_find_last_dir_sep |
||||
int win32_offset_1st_component(const char *path); |
||||
#define offset_1st_component win32_offset_1st_component |
Loading…
Reference in new issue