diff options
Diffstat (limited to 'submodule-config.c')
-rw-r--r-- | submodule-config.c | 131 |
1 files changed, 93 insertions, 38 deletions
diff --git a/submodule-config.c b/submodule-config.c index 5fe2d07877..2aa8a1747f 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) @@ -232,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: @@ -248,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); @@ -277,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: @@ -297,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) @@ -441,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; @@ -464,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; @@ -490,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); @@ -520,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; } @@ -544,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; @@ -559,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) { - 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); } |