X-Git-Url: http://git.tremily.us/?a=blobdiff_plain;f=setup.c;h=f108c4b990c0e4f6a98c1fe34d3031040c84195a;hb=68868ff57348b7ae351890b3599949422d2e6001;hp=3a1b2fd45580cad7ecd55efa755872efc81075ad;hpb=d519e4594c17ea30e33432dd712d2d0887aaf8c7;p=git.git diff --git a/setup.c b/setup.c index 3a1b2fd45..f108c4b99 100644 --- a/setup.c +++ b/setup.c @@ -1,5 +1,6 @@ #include "cache.h" #include "dir.h" +#include "string-list.h" static int inside_git_dir = -1; static int inside_work_tree = -1; @@ -620,6 +621,27 @@ static dev_t get_device_or_die(const char *path, const char *prefix, int prefix_ return buf.st_dev; } +/* + * A "string_list_each_func_t" function that canonicalizes an entry + * from GIT_CEILING_DIRECTORIES using real_path_if_valid(), or + * discards it if unusable. + */ +static int canonicalize_ceiling_entry(struct string_list_item *item, + void *unused) +{ + char *ceil = item->string; + const char *real_path; + + if (!*ceil || !is_absolute_path(ceil)) + return 0; + real_path = real_path_if_valid(ceil); + if (!real_path) + return 0; + free(item->string); + item->string = xstrdup(real_path); + return 1; +} + /* * We cannot decide in this function whether we are in the work tree or * not, since the config can only be read _after_ this function was called. @@ -627,10 +649,11 @@ static dev_t get_device_or_die(const char *path, const char *prefix, int prefix_ static const char *setup_git_directory_gently_1(int *nongit_ok) { const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT); + struct string_list ceiling_dirs = STRING_LIST_INIT_DUP; static char cwd[PATH_MAX+1]; const char *gitdirenv, *ret; char *gitfile; - int len, offset, offset_parent, ceil_offset; + int len, offset, offset_parent, ceil_offset = -1; dev_t current_device = 0; int one_filesystem = 1; @@ -655,7 +678,14 @@ static const char *setup_git_directory_gently_1(int *nongit_ok) if (gitdirenv) return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok); - ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs); + if (env_ceiling_dirs) { + string_list_split(&ceiling_dirs, env_ceiling_dirs, PATH_SEP, -1); + filter_string_list(&ceiling_dirs, 0, + canonicalize_ceiling_entry, NULL); + ceil_offset = longest_ancestor_length(cwd, &ceiling_dirs); + string_list_clear(&ceiling_dirs, 0); + } + if (ceil_offset < 0 && has_dos_drive_prefix(cwd)) ceil_offset = 1;