From: Junio C Hamano Date: Thu, 27 Sep 2018 18:20:22 +0000 (-0700) Subject: Sync with Git 2.14.4 X-Git-Tag: v2.15.3~1 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/902df9f5c45cd99720d4ca0a38d0538eb0126ad7?ds=inline;hp=-c Sync with Git 2.14.4 * maint-2.14: Git 2.14.5 submodule-config: ban submodule paths that start with a dash submodule-config: ban submodule urls that start with dash submodule--helper: use "--" to signal end of clone options --- 902df9f5c45cd99720d4ca0a38d0538eb0126ad7 diff --combined builtin/submodule--helper.c index 77940499b0,676cfed770..30e0bb876c --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@@ -17,8 -17,9 +17,8 @@@ static char *get_default_remote(void) { char *dest = NULL, *ret; - unsigned char sha1[20]; struct strbuf sb = STRBUF_INIT; - const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL); + const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); if (!refname) die(_("No such ref: %s"), "HEAD"); @@@ -274,6 -275,8 +274,6 @@@ static void module_list_active(struct m int i; struct module_list active_modules = MODULE_LIST_INIT; - gitmodules_config(); - for (i = 0; i < list->nr; i++) { const struct cache_entry *ce = list->entries[i]; @@@ -334,6 -337,9 +334,6 @@@ static void init_submodule(const char * struct strbuf sb = STRBUF_INIT; char *upd = NULL, *url = NULL, *displaypath; - /* Only loads from .gitmodules, no overlay with .git/config */ - gitmodules_config(); - if (prefix && get_super_prefix()) die("BUG: cannot have prefix and superprefix"); else if (prefix) @@@ -344,7 -350,7 +344,7 @@@ } else displaypath = xstrdup(path); - sub = submodule_from_path(null_sha1, path); + sub = submodule_from_path(&null_oid, path); if (!sub) die(_("No url found for submodule path '%s' in .gitmodules"), @@@ -469,7 -475,8 +469,7 @@@ static int module_name(int argc, const if (argc != 2) usage(_("git submodule--helper name ")); - gitmodules_config(); - sub = submodule_from_path(null_sha1, argv[1]); + sub = submodule_from_path(&null_oid, argv[1]); if (!sub) die(_("no submodule mapping found in .gitmodules for path '%s'"), @@@ -503,6 -510,7 +503,7 @@@ static int clone_submodule(const char * if (gitdir && *gitdir) argv_array_pushl(&cp.args, "--separate-git-dir", gitdir, NULL); + argv_array_push(&cp.args, "--"); argv_array_push(&cp.args, url); argv_array_push(&cp.args, path); @@@ -773,10 -781,6 +774,10 @@@ static int prepare_to_clone_next_submod struct strbuf *out) { const struct submodule *sub = NULL; + const char *url = NULL; + const char *update_string; + enum submodule_update_type update_type; + char *key; struct strbuf displaypath_sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT; const char *displaypath = NULL; @@@ -792,7 -796,7 +793,7 @@@ goto cleanup; } - sub = submodule_from_path(null_sha1, ce->name); + sub = submodule_from_path(&null_oid, ce->name); if (suc->recursive_prefix) displaypath = relative_path(suc->recursive_prefix, @@@ -805,17 -809,9 +806,17 @@@ goto cleanup; } + key = xstrfmt("submodule.%s.update", sub->name); + if (!repo_config_get_string_const(the_repository, key, &update_string)) { + update_type = parse_submodule_update_type(update_string); + } else { + update_type = sub->update_strategy.type; + } + free(key); + if (suc->update.type == SM_UPDATE_NONE || (suc->update.type == SM_UPDATE_UNSPECIFIED - && sub->update_strategy.type == SM_UPDATE_NONE)) { + && update_type == SM_UPDATE_NONE)) { strbuf_addf(out, _("Skipping submodule '%s'"), displaypath); strbuf_addch(out, '\n'); goto cleanup; @@@ -827,11 -823,6 +828,11 @@@ goto cleanup; } + strbuf_reset(&sb); + strbuf_addf(&sb, "submodule.%s.url", sub->name); + if (repo_config_get_string_const(the_repository, sb.buf, &url)) + url = sub->url; + strbuf_reset(&sb); strbuf_addf(&sb, "%s/.git", ce->name); needs_cloning = !file_exists(sb.buf); @@@ -861,7 -852,7 +862,7 @@@ argv_array_push(&child->args, "--depth=1"); argv_array_pushl(&child->args, "--path", sub->path, NULL); argv_array_pushl(&child->args, "--name", sub->name, NULL); - argv_array_pushl(&child->args, "--url", sub->url, NULL); + argv_array_pushl(&child->args, "--url", url, NULL); if (suc->references.nr) { struct string_list_item *item; for_each_string_list_item(item, &suc->references) @@@ -970,19 -961,10 +971,19 @@@ static int update_clone_task_finished(i return 0; } +static int gitmodules_update_clone_config(const char *var, const char *value, + void *cb) +{ + int *max_jobs = cb; + if (!strcmp(var, "submodule.fetchjobs")) + *max_jobs = parse_submodule_fetchjobs(var, value); + return 0; +} + static int update_clone(int argc, const char **argv, const char *prefix) { const char *update = NULL; - int max_jobs = -1; + int max_jobs = 1; struct string_list_item *item; struct pathspec pathspec; struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; @@@ -1019,9 -1001,6 +1020,9 @@@ }; suc.prefix = prefix; + config_from_gitmodules(gitmodules_update_clone_config, &max_jobs); + git_config(gitmodules_update_clone_config, &max_jobs); + argc = parse_options(argc, argv, prefix, module_update_clone_options, git_submodule_helper_usage, 0); @@@ -1035,6 -1014,13 +1036,6 @@@ if (pathspec.nr) suc.warn_if_uninitialized = 1; - /* Overlay the parsed .gitmodules file with .git/config */ - gitmodules_config(); - git_config(submodule_config, NULL); - - if (max_jobs < 0) - max_jobs = parallel_submodules(); - run_processes_parallel(max_jobs, update_clone_get_next_task, update_clone_start_failure, @@@ -1072,23 -1058,19 +1073,23 @@@ static int resolve_relative_path(int ar static const char *remote_submodule_branch(const char *path) { const struct submodule *sub; - gitmodules_config(); - git_config(submodule_config, NULL); + const char *branch = NULL; + char *key; - sub = submodule_from_path(null_sha1, path); + sub = submodule_from_path(&null_oid, path); if (!sub) return NULL; - if (!sub->branch) + key = xstrfmt("submodule.%s.branch", sub->name); + if (repo_config_get_string_const(the_repository, key, &branch)) + branch = sub->branch; + free(key); + + if (!branch) return "master"; - if (!strcmp(sub->branch, ".")) { - unsigned char sha1[20]; - const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL); + if (!strcmp(branch, ".")) { + const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); if (!refname) die(_("No such ref: %s"), "HEAD"); @@@ -1104,7 -1086,7 +1105,7 @@@ return refname; } - return sub->branch; + return branch; } static int resolve_remote_submodule_branch(int argc, const char **argv, @@@ -1187,7 -1169,6 +1188,7 @@@ static int push_check(int argc, const c break; die("HEAD does not match the named branch in the superproject"); } + /* fallthrough */ default: die("src refspec '%s' must name a ref", rs->src); @@@ -1224,6 -1205,9 +1225,6 @@@ static int absorb_git_dirs(int argc, co argc = parse_options(argc, argv, prefix, embed_gitdir_options, git_submodule_helper_usage, 0); - gitmodules_config(); - git_config(submodule_config, NULL); - if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0) return 1; @@@ -1239,6 -1223,8 +1240,6 @@@ static int is_active(int argc, const ch if (argc != 2) die("submodule--helper is-active takes exactly 1 argument"); - gitmodules_config(); - return !is_submodule_active(the_repository, argv[1]); } diff --combined submodule-config.c index aa02641767,774fb10544..3414fa1c1b --- a/submodule-config.c +++ b/submodule-config.c @@@ -18,7 -18,6 +18,7 @@@ struct submodule_cache struct hashmap for_path; struct hashmap for_name; unsigned initialized:1; + unsigned gitmodules_read:1; }; /* @@@ -36,25 -35,19 +36,25 @@@ enum lookup_type }; static int config_path_cmp(const void *unused_cmp_data, - const struct submodule_entry *a, - const struct submodule_entry *b, + const void *entry, + const void *entry_or_key, const void *unused_keydata) { + const struct submodule_entry *a = entry; + const struct submodule_entry *b = entry_or_key; + return strcmp(a->config->path, b->config->path) || hashcmp(a->config->gitmodules_sha1, b->config->gitmodules_sha1); } static int config_name_cmp(const void *unused_cmp_data, - const struct submodule_entry *a, - const struct submodule_entry *b, + const void *entry, + const void *entry_or_key, const void *unused_keydata) { + const struct submodule_entry *a = entry; + const struct submodule_entry *b = entry_or_key; + return strcmp(a->config->name, b->config->name) || hashcmp(a->config->gitmodules_sha1, b->config->gitmodules_sha1); } @@@ -66,8 -59,8 +66,8 @@@ static struct submodule_cache *submodul static void submodule_cache_init(struct submodule_cache *cache) { - hashmap_init(&cache->for_path, (hashmap_cmp_fn) config_path_cmp, NULL, 0); - hashmap_init(&cache->for_name, (hashmap_cmp_fn) config_name_cmp, NULL, 0); + hashmap_init(&cache->for_path, config_path_cmp, NULL, 0); + hashmap_init(&cache->for_name, config_name_cmp, NULL, 0); cache->initialized = 1; } @@@ -100,7 -93,6 +100,7 @@@ static void submodule_cache_clear(struc hashmap_free(&cache->for_path, 1); hashmap_free(&cache->for_name, 1); cache->initialized = 0; + cache->gitmodules_read = 0; } void submodule_cache_free(struct submodule_cache *cache) @@@ -271,7 -263,7 +271,7 @@@ static struct submodule *lookup_or_crea static int parse_fetch_recurse(const char *opt, const char *arg, int die_on_error) { - switch (git_config_maybe_bool(opt, arg)) { + switch (git_parse_maybe_bool(arg)) { case 1: return RECURSE_SUBMODULES_ON; case 0: @@@ -287,14 -279,6 +287,14 @@@ } } +int parse_submodule_fetchjobs(const char *var, const char *value) +{ + int fetchjobs = git_config_int(var, value); + if (fetchjobs < 0) + die(_("negative values not allowed for submodule.fetchjobs")); + return fetchjobs; +} + int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg) { return parse_fetch_recurse(opt, arg, 1); @@@ -324,7 -308,7 +324,7 @@@ int option_fetch_parse_recurse_submodul static int parse_update_recurse(const char *opt, const char *arg, int die_on_error) { - switch (git_config_maybe_bool(opt, arg)) { + switch (git_parse_maybe_bool(arg)) { case 1: return RECURSE_SUBMODULES_ON; case 0: @@@ -344,7 -328,7 +344,7 @@@ int parse_update_recurse_submodules_arg static int parse_push_recurse(const char *opt, const char *arg, int die_on_error) { - switch (git_config_maybe_bool(opt, arg)) { + switch (git_parse_maybe_bool(arg)) { case 1: /* There's no simple "on" value when pushing */ if (die_on_error) @@@ -383,6 -367,12 +383,12 @@@ static void warn_multiple_config(const commit_string, name, option); } + static void warn_command_line_option(const char *var, const char *value) + { + warning(_("ignoring '%s' which may be interpreted as" + " a command-line option: %s"), var, value); + } + struct parse_config_parameter { struct submodule_cache *cache; const unsigned char *treeish_name; @@@ -408,6 -398,8 +414,8 @@@ static int parse_config(const char *var if (!strcmp(item.buf, "path")) { if (!value) ret = config_error_nonbool(var); + else if (looks_like_command_line_option(value)) + warn_command_line_option(var, value); else if (!me->overwrite && submodule->path) warn_multiple_config(me->treeish_name, submodule->name, "path"); @@@ -448,6 -440,8 +456,8 @@@ } else if (!strcmp(item.buf, "url")) { if (!value) { ret = config_error_nonbool(var); + } else if (looks_like_command_line_option(value)) { + warn_command_line_option(var, value); } else if (!me->overwrite && submodule->url) { warn_multiple_config(me->treeish_name, submodule->name, "url"); @@@ -488,19 -482,19 +498,19 @@@ return ret; } -int gitmodule_sha1_from_commit(const unsigned char *treeish_name, - unsigned char *gitmodules_sha1, - struct strbuf *rev) +static int gitmodule_oid_from_commit(const struct object_id *treeish_name, + struct object_id *gitmodules_oid, + struct strbuf *rev) { int ret = 0; - if (is_null_sha1(treeish_name)) { - hashclr(gitmodules_sha1); + if (is_null_oid(treeish_name)) { + oidclr(gitmodules_oid); return 1; } - strbuf_addf(rev, "%s:.gitmodules", sha1_to_hex(treeish_name)); - if (get_sha1(rev->buf, gitmodules_sha1) >= 0) + strbuf_addf(rev, "%s:.gitmodules", oid_to_hex(treeish_name)); + if (get_oid(rev->buf, gitmodules_oid) >= 0) ret = 1; return ret; @@@ -511,13 -505,13 +521,13 @@@ * revisions. */ static const struct submodule *config_from(struct submodule_cache *cache, - const unsigned char *treeish_name, const char *key, + const struct object_id *treeish_name, const char *key, enum lookup_type lookup_type) { struct strbuf rev = STRBUF_INIT; unsigned long config_size; char *config = NULL; - unsigned char sha1[20]; + struct object_id oid; enum object_type type; const struct submodule *submodule = NULL; struct parse_config_parameter parameter; @@@ -537,28 -531,28 +547,28 @@@ return entry->config; } - if (!gitmodule_sha1_from_commit(treeish_name, sha1, &rev)) + if (!gitmodule_oid_from_commit(treeish_name, &oid, &rev)) goto out; switch (lookup_type) { case lookup_name: - submodule = cache_lookup_name(cache, sha1, key); + submodule = cache_lookup_name(cache, oid.hash, key); break; case lookup_path: - submodule = cache_lookup_path(cache, sha1, key); + submodule = cache_lookup_path(cache, oid.hash, key); break; } if (submodule) goto out; - config = read_sha1_file(sha1, &type, &config_size); + config = read_sha1_file(oid.hash, &type, &config_size); if (!config || type != OBJ_BLOB) goto out; /* fill the submodule config into the cache */ parameter.cache = cache; - parameter.treeish_name = treeish_name; - parameter.gitmodules_sha1 = sha1; + parameter.treeish_name = treeish_name->hash; + parameter.gitmodules_sha1 = oid.hash; parameter.overwrite = 0; git_config_from_mem(parse_config, CONFIG_ORIGIN_SUBMODULE_BLOB, rev.buf, config, config_size, ¶meter); @@@ -567,9 -561,9 +577,9 @@@ switch (lookup_type) { case lookup_name: - return cache_lookup_name(cache, sha1, key); + return cache_lookup_name(cache, oid.hash, key); case lookup_path: - return cache_lookup_path(cache, sha1, key); + return cache_lookup_path(cache, oid.hash, key); default: return NULL; } @@@ -591,11 -585,13 +601,11 @@@ static void submodule_cache_check_init( submodule_cache_init(repo->submodule_cache); } -int submodule_config_option(struct repository *repo, - const char *var, const char *value) +static int gitmodules_cb(const char *var, const char *value, void *data) { + struct repository *repo = data; struct parse_config_parameter parameter; - submodule_cache_check_init(repo); - parameter.cache = repo->submodule_cache; parameter.treeish_name = NULL; parameter.gitmodules_sha1 = null_sha1; @@@ -604,71 -600,30 +614,71 @@@ return parse_config(var, value, ¶meter); } -int parse_submodule_config_option(const char *var, const char *value) +void repo_read_gitmodules(struct repository *repo) { - return submodule_config_option(the_repository, var, value); + submodule_cache_check_init(repo); + + if (repo->worktree) { + char *gitmodules; + + if (repo_read_index(repo) < 0) + return; + + gitmodules = repo_worktree_path(repo, GITMODULES_FILE); + + if (!is_gitmodules_unmerged(repo->index)) + git_config_from_file(gitmodules_cb, gitmodules, repo); + + free(gitmodules); + } + + repo->submodule_cache->gitmodules_read = 1; } -const struct submodule *submodule_from_name(const unsigned char *treeish_name, - const char *name) +void gitmodules_config_oid(const struct object_id *commit_oid) { + struct strbuf rev = STRBUF_INIT; + struct object_id oid; + submodule_cache_check_init(the_repository); + + if (gitmodule_oid_from_commit(commit_oid, &oid, &rev)) { + git_config_from_blob_oid(gitmodules_cb, rev.buf, + &oid, the_repository); + } + strbuf_release(&rev); + + the_repository->submodule_cache->gitmodules_read = 1; +} + +static void gitmodules_read_check(struct repository *repo) +{ + submodule_cache_check_init(repo); + + /* read the repo's .gitmodules file if it hasn't been already */ + if (!repo->submodule_cache->gitmodules_read) + repo_read_gitmodules(repo); +} + +const struct submodule *submodule_from_name(const struct object_id *treeish_name, + const char *name) +{ + gitmodules_read_check(the_repository); return config_from(the_repository->submodule_cache, treeish_name, name, lookup_name); } -const struct submodule *submodule_from_path(const unsigned char *treeish_name, +const struct submodule *submodule_from_path(const struct object_id *treeish_name, const char *path) { - submodule_cache_check_init(the_repository); + gitmodules_read_check(the_repository); return config_from(the_repository->submodule_cache, treeish_name, path, lookup_path); } const struct submodule *submodule_from_cache(struct repository *repo, - const unsigned char *treeish_name, + const struct object_id *treeish_name, const char *key) { - submodule_cache_check_init(repo); + gitmodules_read_check(repo); return config_from(repo->submodule_cache, treeish_name, key, lookup_path); }