diff options
Diffstat (limited to 'submodule-config.c')
-rw-r--r-- | submodule-config.c | 146 |
1 files changed, 131 insertions, 15 deletions
diff --git a/submodule-config.c b/submodule-config.c index 6b212bae31..52702c62d9 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -1,9 +1,11 @@ #include "cache.h" +#include "dir.h" #include "repository.h" #include "config.h" #include "submodule-config.h" #include "submodule.h" #include "strbuf.h" +#include "object-store.h" #include "parse-options.h" /* @@ -44,7 +46,7 @@ static int config_path_cmp(const void *unused_cmp_data, const struct submodule_entry *b = entry_or_key; return strcmp(a->config->path, b->config->path) || - oidcmp(&a->config->gitmodules_oid, &b->config->gitmodules_oid); + !oideq(&a->config->gitmodules_oid, &b->config->gitmodules_oid); } static int config_name_cmp(const void *unused_cmp_data, @@ -56,7 +58,7 @@ static int config_name_cmp(const void *unused_cmp_data, const struct submodule_entry *b = entry_or_key; return strcmp(a->config->name, b->config->name) || - oidcmp(&a->config->gitmodules_oid, &b->config->gitmodules_oid); + !oideq(&a->config->gitmodules_oid, &b->config->gitmodules_oid); } static struct submodule_cache *submodule_cache_alloc(void) @@ -571,7 +573,7 @@ static const struct submodule *config_from(struct submodule_cache *cache, parameter.gitmodules_oid = &oid; parameter.overwrite = 0; git_config_from_mem(parse_config, CONFIG_ORIGIN_SUBMODULE_BLOB, rev.buf, - config, config_size, ¶meter); + config, config_size, ¶meter, NULL); strbuf_release(&rev); free(config); @@ -601,6 +603,49 @@ static void submodule_cache_check_init(struct repository *repo) submodule_cache_init(repo->submodule_cache); } +/* + * Note: This function is private for a reason, the '.gitmodules' file should + * not be used as as a mechanism to retrieve arbitrary configuration stored in + * the repository. + * + * Runs the provided config function on the '.gitmodules' file found in the + * working directory. + */ +static void config_from_gitmodules(config_fn_t fn, struct repository *repo, void *data) +{ + if (repo->worktree) { + struct git_config_source config_source = { 0 }; + const struct config_options opts = { 0 }; + struct object_id oid; + char *file; + + file = repo_worktree_path(repo, GITMODULES_FILE); + if (file_exists(file)) { + config_source.file = file; + } else if (repo->submodule_prefix) { + /* + * When get_oid and config_with_options, used below, + * become able to work on a specific repository, this + * warning branch can be removed. + */ + warning("nested submodules without %s in the working tree are not supported yet", + GITMODULES_FILE); + goto out; + } else if (get_oid(GITMODULES_INDEX, &oid) >= 0) { + config_source.blob = GITMODULES_INDEX; + } else if (get_oid(GITMODULES_HEAD, &oid) >= 0) { + config_source.blob = GITMODULES_HEAD; + } else { + goto out; + } + + config_with_options(fn, data, &config_source, &opts); + +out: + free(file); + } +} + static int gitmodules_cb(const char *var, const char *value, void *data) { struct repository *repo = data; @@ -618,19 +663,11 @@ 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); + if (repo_read_index(repo) < 0) + return; - free(gitmodules); - } + if (!is_gitmodules_unmerged(repo->index)) + config_from_gitmodules(gitmodules_cb, repo, repo); repo->submodule_cache->gitmodules_read = 1; } @@ -681,3 +718,82 @@ void submodule_free(struct repository *r) if (r->submodule_cache) submodule_cache_clear(r->submodule_cache); } + +static int config_print_callback(const char *var, const char *value, void *cb_data) +{ + char *wanted_key = cb_data; + + if (!strcmp(wanted_key, var)) + printf("%s\n", value); + + return 0; +} + +int print_config_from_gitmodules(struct repository *repo, const char *key) +{ + int ret; + char *store_key; + + ret = git_config_parse_key(key, &store_key, NULL); + if (ret < 0) + return CONFIG_INVALID_KEY; + + config_from_gitmodules(config_print_callback, repo, store_key); + + free(store_key); + return 0; +} + +int config_set_in_gitmodules_file_gently(const char *key, const char *value) +{ + int ret; + + ret = git_config_set_in_file_gently(GITMODULES_FILE, key, value); + if (ret < 0) + /* Maybe the user already did that, don't error out here */ + warning(_("Could not update .gitmodules entry %s"), key); + + return ret; +} + +struct fetch_config { + int *max_children; + int *recurse_submodules; +}; + +static int gitmodules_fetch_config(const char *var, const char *value, void *cb) +{ + struct fetch_config *config = cb; + if (!strcmp(var, "submodule.fetchjobs")) { + *(config->max_children) = parse_submodule_fetchjobs(var, value); + return 0; + } else if (!strcmp(var, "fetch.recursesubmodules")) { + *(config->recurse_submodules) = parse_fetch_recurse_submodules_arg(var, value); + return 0; + } + + return 0; +} + +void fetch_config_from_gitmodules(int *max_children, int *recurse_submodules) +{ + struct fetch_config config = { + .max_children = max_children, + .recurse_submodules = recurse_submodules + }; + config_from_gitmodules(gitmodules_fetch_config, the_repository, &config); +} + +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; +} + +void update_clone_config_from_gitmodules(int *max_jobs) +{ + config_from_gitmodules(gitmodules_update_clone_config, the_repository, &max_jobs); +} |