X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=setup.c;h=2ae57f7c94e304ef3468a27cd245c314a08046ed;hb=60c0f8462fefed22fc8fb9c4e529665ed8204536;hp=fe7f8846962d1c656d258384dbfa466031e28896;hpb=b0121fb3f279a9cf13aff9da060e742aef3a83fa;p=git.git diff --git a/setup.c b/setup.c index fe7f88469..2ae57f7c9 100644 --- a/setup.c +++ b/setup.c @@ -131,28 +131,46 @@ const char **get_pathspec(const char *prefix, const char **pathspec) } /* - * Test if it looks like we're at the top level git directory. + * Test if it looks like we're at a git directory. * We want to see: * - * - either a .git/objects/ directory _or_ the proper + * - either a objects/ directory _or_ the proper * GIT_OBJECT_DIRECTORY environment variable - * - a refs/ directory under ".git" + * - a refs/ directory * - either a HEAD symlink or a HEAD file that is formatted as * a proper "ref:". */ -static int is_toplevel_directory(void) +static int is_git_directory(const char *suspect) { - if (access(".git/refs/", X_OK) || - access(getenv(DB_ENVIRONMENT) ? - getenv(DB_ENVIRONMENT) : ".git/objects/", X_OK) || - validate_symref(".git/HEAD")) + char path[PATH_MAX]; + size_t len = strlen(suspect); + + strcpy(path, suspect); + if (getenv(DB_ENVIRONMENT)) { + if (access(getenv(DB_ENVIRONMENT), X_OK)) + return 0; + } + else { + strcpy(path + len, "/objects"); + if (access(path, X_OK)) + return 0; + } + + strcpy(path + len, "/refs"); + if (access(path, X_OK)) return 0; + + strcpy(path + len, "/HEAD"); + if (validate_symref(path)) + return 0; + return 1; } const char *setup_git_directory_gently(int *nongit_ok) { static char cwd[PATH_MAX+1]; + const char *gitdirenv; int len, offset; /* @@ -160,32 +178,17 @@ const char *setup_git_directory_gently(int *nongit_ok) * to do any discovery, but we still do repository * validation. */ - if (getenv(GIT_DIR_ENVIRONMENT)) { - char path[PATH_MAX]; - int len = strlen(getenv(GIT_DIR_ENVIRONMENT)); - if (sizeof(path) - 40 < len) + gitdirenv = getenv(GIT_DIR_ENVIRONMENT); + if (gitdirenv) { + if (PATH_MAX - 40 < strlen(gitdirenv)) die("'$%s' too big", GIT_DIR_ENVIRONMENT); - memcpy(path, getenv(GIT_DIR_ENVIRONMENT), len); - - strcpy(path + len, "/refs"); - if (access(path, X_OK)) - goto bad_dir_environ; - strcpy(path + len, "/HEAD"); - if (validate_symref(path)) - goto bad_dir_environ; - if (getenv(DB_ENVIRONMENT)) { - if (access(getenv(DB_ENVIRONMENT), X_OK)) - goto bad_dir_environ; - } - else { - strcpy(path + len, "/objects"); - if (access(path, X_OK)) - goto bad_dir_environ; + if (is_git_directory(gitdirenv)) + return NULL; + if (nongit_ok) { + *nongit_ok = 1; + return NULL; } - return NULL; - bad_dir_environ: - path[len] = 0; - die("Not a git repository: '%s'", path); + die("Not a git repository: '%s'", gitdirenv); } if (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/') @@ -193,11 +196,17 @@ const char *setup_git_directory_gently(int *nongit_ok) offset = len = strlen(cwd); for (;;) { - if (is_toplevel_directory()) + if (is_git_directory(".git")) break; chdir(".."); do { if (!offset) { + if (is_git_directory(cwd)) { + if (chdir(cwd)) + die("Cannot come back to cwd"); + setenv(GIT_DIR_ENVIRONMENT, cwd, 1); + return NULL; + } if (nongit_ok) { if (chdir(cwd)) die("Cannot come back to cwd"); @@ -219,12 +228,27 @@ const char *setup_git_directory_gently(int *nongit_ok) return cwd + offset; } +int git_config_perm(const char *var, const char *value) +{ + if (value) { + 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; + } + return git_config_bool(var, value); +} + int check_repository_format_version(const char *var, const char *value) { if (strcmp(var, "core.repositoryformatversion") == 0) repository_format_version = git_config_int(var, value); else if (strcmp(var, "core.sharedrepository") == 0) - shared_repository = git_config_bool(var, value); + shared_repository = git_config_perm(var, value); return 0; }