index 53580fde43ce01f12dc326b419d94573ea14787a..cc3fb380c1f3471f0371ba54ca2f338f90a8d4fc 100644 (file)
--- a/setup.c
+++ b/setup.c
static int sanitary_path_copy(char *dst, const char *src)
{
- char *dst0 = dst;
+ char *dst0;
- if (*src == '/') {
+ if (has_dos_drive_prefix(src)) {
+ *dst++ = *src++;
+ *dst++ = *src++;
+ }
+ dst0 = dst;
+
+ if (is_dir_sep(*src)) {
*dst++ = '/';
- while (*src == '/')
+ while (is_dir_sep(*src))
src++;
}
* (4) "../" -- strip one, eat slash and continue.
*/
if (c == '.') {
- switch (src[1]) {
- case '\0':
+ if (!src[1]) {
/* (1) */
src++;
- break;
- case '/':
+ } else if (is_dir_sep(src[1])) {
/* (2) */
src += 2;
- while (*src == '/')
+ while (is_dir_sep(*src))
src++;
continue;
- case '.':
- switch (src[2]) {
- case '\0':
+ } else if (src[1] == '.') {
+ if (!src[2]) {
/* (3) */
src += 2;
goto up_one;
- case '/':
+ } else if (is_dir_sep(src[2])) {
/* (4) */
src += 3;
- while (*src == '/')
+ while (is_dir_sep(*src))
src++;
goto up_one;
}
}
/* copy up to the next '/', and eat all '/' */
- while ((c = *src++) != '\0' && c != '/')
+ while ((c = *src++) != '\0' && !is_dir_sep(c))
*dst++ = c;
- if (c == '/') {
- *dst++ = c;
- while (c == '/')
+ if (is_dir_sep(c)) {
+ *dst++ = '/';
+ while (is_dir_sep(c))
c = *src++;
src--;
} else if (!c)
if (dst <= dst0)
break;
c = *dst--;
- if (c == '/') {
+ if (c == '/') { /* MinGW: cannot be '\\' anymore */
dst += 2;
break;
}
const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
{
static char path[PATH_MAX];
+#ifndef __MINGW32__
if (!pfx || !*pfx || is_absolute_path(arg))
return arg;
memcpy(path, pfx, pfx_len);
strcpy(path + pfx_len, arg);
+#else
+ char *p;
+ /* don't add prefix to absolute paths, but still replace '\' by '/' */
+ if (is_absolute_path(arg))
+ pfx_len = 0;
+ else
+ memcpy(path, pfx, pfx_len);
+ strcpy(path + pfx_len, arg);
+ for (p = path + pfx_len; *p; p++)
+ if (*p == '\\')
+ *p = '/';
+#endif
return path;
}
work_tree = get_git_work_tree();
git_dir = get_git_dir();
if (!is_absolute_path(git_dir))
- set_git_dir(make_absolute_path(git_dir));
+ git_dir = make_absolute_path(git_dir);
if (!work_tree || chdir(work_tree))
die("This operation must be run in a work tree");
+ set_git_dir(make_relative_path(git_dir, work_tree));
initialized = 1;
}
static int check_repository_format_gently(int *nongit_ok)
{
- git_config(check_repository_format_version);
+ git_config(check_repository_format_version, NULL);
if (GIT_REPO_VERSION < repository_format_version) {
if (!nongit_ok)
die ("Expected git repo version <= %d, found %d",
const char *gitdirenv;
const char *gitfile_dir;
int len, offset;
+ int minoffset = 0;
/*
* Let's assume that we are in a git repository.
if (!getcwd(cwd, sizeof(cwd)-1))
die("Unable to read current working directory");
+ if (has_dos_drive_prefix(cwd))
+ minoffset = 2;
/*
* Test in the following order (relative to the cwd):
}
chdir("..");
do {
- if (!offset) {
+ if (offset <= minoffset) {
if (nongit_ok) {
if (chdir(cwd))
die("Cannot come back to cwd");
}
die("Not a git repository");
}
- } while (cwd[--offset] != '/');
+ } while (offset > minoffset && cwd[--offset] != '/');
}
inside_git_dir = 0;
int git_config_perm(const char *var, const char *value)
{
- if (value) {
- int i;
- if (!strcmp(value, "umask"))
- return PERM_UMASK;
- if (!strcmp(value, "group"))
- return PERM_GROUP;
- if (!strcmp(value, "all") ||
- !strcmp(value, "world") ||
- !strcmp(value, "everybody"))
- return PERM_EVERYBODY;
- i = atoi(value);
- if (i > 1)
- return i;
+ int i;
+ char *endptr;
+
+ if (value == NULL)
+ return PERM_GROUP;
+
+ if (!strcmp(value, "umask"))
+ return PERM_UMASK;
+ if (!strcmp(value, "group"))
+ return PERM_GROUP;
+ if (!strcmp(value, "all") ||
+ !strcmp(value, "world") ||
+ !strcmp(value, "everybody"))
+ return PERM_EVERYBODY;
+
+ /* Parse octal numbers */
+ i = strtol(value, &endptr, 8);
+
+ /* If not an octal number, maybe true/false? */
+ if (*endptr != 0)
+ return git_config_bool(var, value) ? PERM_GROUP : PERM_UMASK;
+
+ /*
+ * Treat values 0, 1 and 2 as compatibility cases, otherwise it is
+ * a chmod value.
+ */
+ switch (i) {
+ case PERM_UMASK: /* 0 */
+ return PERM_UMASK;
+ case OLD_PERM_GROUP: /* 1 */
+ return PERM_GROUP;
+ case OLD_PERM_EVERYBODY: /* 2 */
+ return PERM_EVERYBODY;
}
- return git_config_bool(var, value);
+
+ /* A filemode value was given: 0xxx */
+
+ if ((i & 0600) != 0600)
+ die("Problem with core.sharedRepository filemode value "
+ "(0%.3o).\nThe owner of files must always have "
+ "read and write permissions.", i);
+
+ /*
+ * Mask filemode value. Others can not get write permission.
+ * x flags for directories are handled separately.
+ */
+ return i & 0666;
}
-int check_repository_format_version(const char *var, const char *value)
+int check_repository_format_version(const char *var, const char *value, void *cb)
{
if (strcmp(var, "core.repositoryformatversion") == 0)
repository_format_version = git_config_int(var, value);