diff options
Diffstat (limited to 'setup.c')
-rw-r--r-- | setup.c | 42 |
1 files changed, 34 insertions, 8 deletions
@@ -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; @@ -77,9 +78,6 @@ static void NORETURN die_verify_filename(const char *prefix, const char *arg, int diagnose_misspelt_rev) { - unsigned char sha1[20]; - unsigned mode; - if (!diagnose_misspelt_rev) die("%s: no such path in the working tree.\n" "Use 'git <command> -- <path>...' to specify paths that do not exist locally.", @@ -88,11 +86,10 @@ static void NORETURN die_verify_filename(const char *prefix, * Saying "'(icase)foo' does not exist in the index" when the * user gave us ":(icase)foo" is just stupid. A magic pathspec * begins with a colon and is followed by a non-alnum; do not - * let get_sha1_with_mode_1(only_to_die=1) to even trigger. + * let maybe_die_on_misspelt_object_name() even trigger. */ if (!(arg[0] == ':' && !isalnum(arg[1]))) - /* try a detailed diagnostic ... */ - get_sha1_with_mode_1(arg, sha1, &mode, 1, prefix); + maybe_die_on_misspelt_object_name(arg, prefix); /* ... or fall back the most general message. */ die("ambiguous argument '%s': unknown revision or path not in the working tree.\n" @@ -644,16 +641,38 @@ static dev_t get_device_or_die(const char *path, const char *prefix, int prefix_ } /* + * 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. */ 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; @@ -678,7 +697,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; |