X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=submodule-config.c;h=2aa8a1747f8586839aa3036fbbc59f6c716c6128;hb=e3b7705207b3e9c661026e43b95cfb2f40d7e6f2;hp=774fb105440a431d741124278987151ac2ea9166;hpb=d6e11a6ebb61d22349f15df790fc8fe080ad5b52;p=platform%2Fupstream%2Fgit.git diff --git a/submodule-config.c b/submodule-config.c index 774fb10..2aa8a17 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -18,6 +18,7 @@ struct submodule_cache { struct hashmap for_path; struct hashmap for_name; unsigned initialized:1; + unsigned gitmodules_read:1; }; /* @@ -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); } @@ -59,8 +66,8 @@ static struct submodule_cache *submodule_cache_alloc(void) 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; } @@ -93,6 +100,7 @@ static void submodule_cache_clear(struct submodule_cache *cache) 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) @@ -182,31 +190,6 @@ static struct submodule *cache_lookup_name(struct submodule_cache *cache, return NULL; } -int check_submodule_name(const char *name) -{ - /* Disallow empty names */ - if (!*name) - return -1; - - /* - * Look for '..' as a path component. Check both '/' and '\\' as - * separators rather than is_dir_sep(), because we want the name rules - * to be consistent across platforms. - */ - goto in_component; /* always start inside component */ - while (*name) { - char c = *name++; - if (c == '/' || c == '\\') { -in_component: - if (name[0] == '.' && name[1] == '.' && - (!name[2] || name[2] == '/' || name[2] == '\\')) - return -1; - } - } - - return 0; -} - static int name_and_item_from_var(const char *var, struct strbuf *name, struct strbuf *item) { @@ -218,12 +201,6 @@ static int name_and_item_from_var(const char *var, struct strbuf *name, return 0; strbuf_add(name, subsection, subsection_len); - if (check_submodule_name(name->buf) < 0) { - warning(_("ignoring suspicious submodule name: %s"), name->buf); - strbuf_release(name); - return 0; - } - strbuf_addstr(item, key); return 1; @@ -263,7 +240,7 @@ static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache, 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: @@ -279,6 +256,14 @@ static int parse_fetch_recurse(const char *opt, const char *arg, } } +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); @@ -308,7 +293,7 @@ int option_fetch_parse_recurse_submodules(const struct option *opt, 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: @@ -328,7 +313,7 @@ int parse_update_recurse_submodules_arg(const char *opt, const char *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) @@ -367,12 +352,6 @@ static void warn_multiple_config(const unsigned char *treeish_name, 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; @@ -398,8 +377,6 @@ static int parse_config(const char *var, const char *value, void *data) 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"); @@ -440,8 +417,6 @@ static int parse_config(const char *var, const char *value, void *data) } 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"); @@ -482,19 +457,19 @@ static int parse_config(const char *var, const char *value, void *data) 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; @@ -505,13 +480,13 @@ int gitmodule_sha1_from_commit(const unsigned char *treeish_name, * 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; @@ -531,28 +506,28 @@ static const struct submodule *config_from(struct submodule_cache *cache, 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); @@ -561,9 +536,9 @@ static const struct submodule *config_from(struct submodule_cache *cache, 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; } @@ -585,13 +560,11 @@ static void submodule_cache_check_init(struct repository *repo) 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; @@ -600,30 +573,71 @@ int submodule_config_option(struct repository *repo, return parse_config(var, value, ¶meter); } -int parse_submodule_config_option(const char *var, const char *value) +void repo_read_gitmodules(struct repository *repo) +{ + 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; +} + +void gitmodules_config_oid(const struct object_id *commit_oid) { - return submodule_config_option(the_repository, var, value); + 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 unsigned char *treeish_name, +const struct submodule *submodule_from_name(const struct object_id *treeish_name, const char *name) { - submodule_cache_check_init(the_repository); + 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); }