Windows: Treat Windows style path names.
GIT's guts work with a forward slash as a path separators. We do not change that. Rather we make sure that only "normalized" paths enter the depths of the machinery. We have to translate backslashes to forward slashes in the prefix and in command line arguments. Fortunately, all of them are passed through functions in setup.c. A macro has_dos_drive_path() is defined that checks whether a path begins with a drive letter+colon combination. This predicate is always false on Unix. Another macro is_dir_sep() abstracts that a backslash is also a directory separator on Windows. Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Johannes Sixt committed
Mar 5, 2008 at 21:51 UTC
25fe217b86ca40c53e710d776e120dfa0d81f60b
5 files changed
+67
-15
cache.h
+1
-1
@@ -521,7 +521,7 @@ int safe_create_leading_directories(char *path);
521
char *enter_repo(char *path, int strict);
522
static inline int is_absolute_path(const char *path)
523
{
524
- return path[0] == '/';
524
+ return path[0] == '/' || has_dos_drive_prefix(path);
525
}
526
const char *make_absolute_path(const char *path);
527
const char *make_nonrelative_path(const char *path);
compat/mingw.c
+13
@@ -40,6 +40,19 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
40
return result;
41
}
42
43
+#undef getcwd
44
+char *mingw_getcwd(char *pointer, int len)
45
+{
46
+ int i;
47
+ char *ret = getcwd(pointer, len);
48
+ if (!ret)
49
+ return ret;
50
+ for (i = 0; pointer[i]; i++)
51
+ if (pointer[i] == '\\')
52
+ pointer[i] = '/';
53
+ return ret;
54
+}
55
+
56
struct passwd *getpwuid(int uid)
57
{
58
static struct passwd p;
compat/mingw.h
+9
@@ -133,8 +133,17 @@ struct passwd *getpwuid(int uid);
133
int setitimer(int type, struct itimerval *in, struct itimerval *out);
134
int sigaction(int sig, struct sigaction *in, struct sigaction *out);
135
136
+/*
137
+ * replacements of existing functions
138
+ */
139
+
140
+char *mingw_getcwd(char *pointer, int len);
141
+#define getcwd mingw_getcwd
142
+
143
/*
144
* git specific compatibility
145
*/
146
147
+#define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':')
148
+#define is_dir_sep(c) ((c) == '/' || (c) == '\\')
149
#define PATH_SEP ';'
git-compat-util.h
+8
@@ -114,6 +114,14 @@
114
#define PATH_SEP ':'
115
#endif
116
117
+#ifndef has_dos_drive_prefix
118
+#define has_dos_drive_prefix(path) 0
119
+#endif
120
+
121
+#ifndef is_dir_sep
122
+#define is_dir_sep(c) ((c) == '/')
123
+#endif
124
+
125
#ifdef __GNUC__
126
#define NORETURN __attribute__((__noreturn__))
127
#else
setup.c
+36
-14
@@ -6,11 +6,17 @@ static int inside_work_tree = -1;
6
7
static int sanitary_path_copy(char *dst, const char *src)
8
{
9
- char *dst0 = dst;
9
+ char *dst0;
10
11
- if (*src == '/') {
11
+ if (has_dos_drive_prefix(src)) {
12
+ *dst++ = *src++;
13
+ *dst++ = *src++;
14
+ }
15
+ dst0 = dst;
16
+
17
+ if (is_dir_sep(*src)) {
18
*dst++ = '/';
13
- while (*src == '/')
19
+ while (is_dir_sep(*src))
20
src++;
21
}
22
@@ -29,10 +35,10 @@ static int sanitary_path_copy(char *dst, const char *src)
35
if (!src[1]) {
36
/* (1) */
37
src++;
32
- } else if (src[1] == '/') {
38
+ } else if (is_dir_sep(src[1])) {
39
/* (2) */
40
src += 2;
35
- while (*src == '/')
41
+ while (is_dir_sep(*src))
42
src++;
43
continue;
44
} else if (src[1] == '.') {
@@ -40,10 +46,10 @@ static int sanitary_path_copy(char *dst, const char *src)
46
/* (3) */
47
src += 2;
48
goto up_one;
43
- } else if (src[2] == '/') {
49
+ } else if (is_dir_sep(src[2])) {
50
/* (4) */
51
src += 3;
46
- while (*src == '/')
52
+ while (is_dir_sep(*src))
53
src++;
54
goto up_one;
55
}
@@ -51,11 +57,11 @@ static int sanitary_path_copy(char *dst, const char *src)
57
}
58
59
/* copy up to the next '/', and eat all '/' */
54
- while ((c = *src++) != '\0' && c != '/')
60
+ while ((c = *src++) != '\0' && !is_dir_sep(c))
61
*dst++ = c;
56
- if (c == '/') {
57
- *dst++ = c;
58
- while (c == '/')
62
+ if (is_dir_sep(c)) {
63
+ *dst++ = '/';
64
+ while (is_dir_sep(c))
65
c = *src++;
66
src--;
67
} else if (!c)
@@ -74,7 +80,7 @@ static int sanitary_path_copy(char *dst, const char *src)
80
if (dst <= dst0)
81
break;
82
c = *dst--;
77
- if (c == '/') {
83
+ if (c == '/') { /* MinGW: cannot be '\\' anymore */
84
dst += 2;
85
break;
86
}
@@ -123,10 +129,23 @@ const char *prefix_path(const char *prefix, int len, const char *path)
129
const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
130
{
131
static char path[PATH_MAX];
132
+#ifndef __MINGW32__
133
if (!pfx || !*pfx || is_absolute_path(arg))
134
return arg;
135
memcpy(path, pfx, pfx_len);
136
strcpy(path + pfx_len, arg);
137
+#else
138
+ char *p;
139
+ /* don't add prefix to absolute paths, but still replace '\' by '/' */
140
+ if (is_absolute_path(arg))
141
+ pfx_len = 0;
142
+ else
143
+ memcpy(path, pfx, pfx_len);
144
+ strcpy(path + pfx_len, arg);
145
+ for (p = path + pfx_len; *p; p++)
146
+ if (*p == '\\')
147
+ *p = '/';
148
+#endif
149
return path;
150
}
151
@@ -360,6 +379,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
379
const char *gitdirenv;
380
const char *gitfile_dir;
381
int len, offset;
382
+ int minoffset = 0;
383
384
/*
385
* Let's assume that we are in a git repository.
@@ -410,6 +430,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
430
431
if (!getcwd(cwd, sizeof(cwd)-1))
432
die("Unable to read current working directory");
433
+ if (has_dos_drive_prefix(cwd))
434
+ minoffset = 2;
435
436
/*
437
* Test in the following order (relative to the cwd):
@@ -442,7 +464,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
464
}
465
chdir("..");
466
do {
445
- if (!offset) {
467
+ if (offset <= minoffset) {
468
if (nongit_ok) {
469
if (chdir(cwd))
470
die("Cannot come back to cwd");
@@ -451,7 +473,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
473
}
474
die("Not a git repository");
475
}
454
- } while (cwd[--offset] != '/');
476
+ } while (offset > minoffset && cwd[--offset] != '/');
477
}
478
479
inside_git_dir = 0;