diff options
Diffstat (limited to 'submodule-config.c')
-rw-r--r-- | submodule-config.c | 173 |
1 files changed, 109 insertions, 64 deletions
diff --git a/submodule-config.c b/submodule-config.c index aa02641767..e04ba756d9 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -4,12 +4,13 @@ #include "submodule-config.h" #include "submodule.h" #include "strbuf.h" +#include "object-store.h" #include "parse-options.h" /* * submodule cache lookup structure * There is one shared set of 'struct submodule' entries which can be - * looked up by their sha1 blob id of the .gitmodule file and either + * looked up by their sha1 blob id of the .gitmodules file and either * using path or name as key. * for_path stores submodule entries with path as key * for_name stores submodule entries with name as key @@ -44,7 +45,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) || - hashcmp(a->config->gitmodules_sha1, b->config->gitmodules_sha1); + !oideq(&a->config->gitmodules_oid, &b->config->gitmodules_oid); } static int config_name_cmp(const void *unused_cmp_data, @@ -56,7 +57,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) || - hashcmp(a->config->gitmodules_sha1, b->config->gitmodules_sha1); + !oideq(&a->config->gitmodules_oid, &b->config->gitmodules_oid); } static struct submodule_cache *submodule_cache_alloc(void) @@ -91,7 +92,7 @@ static void submodule_cache_clear(struct submodule_cache *cache) /* * We iterate over the name hash here to be symmetric with the * allocation of struct submodule entries. Each is allocated by - * their .gitmodule blob sha1 and submodule name. + * their .gitmodules blob sha1 and submodule name. */ hashmap_iter_init(&cache->for_name, &iter); while ((entry = hashmap_iter_next(&iter))) @@ -109,17 +110,17 @@ void submodule_cache_free(struct submodule_cache *cache) free(cache); } -static unsigned int hash_sha1_string(const unsigned char *sha1, - const char *string) +static unsigned int hash_oid_string(const struct object_id *oid, + const char *string) { - return memhash(sha1, 20) + strhash(string); + return memhash(oid->hash, the_hash_algo->rawsz) + strhash(string); } static void cache_put_path(struct submodule_cache *cache, struct submodule *submodule) { - unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1, - submodule->path); + unsigned int hash = hash_oid_string(&submodule->gitmodules_oid, + submodule->path); struct submodule_entry *e = xmalloc(sizeof(*e)); hashmap_entry_init(e, hash); e->config = submodule; @@ -129,8 +130,8 @@ static void cache_put_path(struct submodule_cache *cache, static void cache_remove_path(struct submodule_cache *cache, struct submodule *submodule) { - unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1, - submodule->path); + unsigned int hash = hash_oid_string(&submodule->gitmodules_oid, + submodule->path); struct submodule_entry e; struct submodule_entry *removed; hashmap_entry_init(&e, hash); @@ -142,8 +143,8 @@ static void cache_remove_path(struct submodule_cache *cache, static void cache_add(struct submodule_cache *cache, struct submodule *submodule) { - unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1, - submodule->name); + unsigned int hash = hash_oid_string(&submodule->gitmodules_oid, + submodule->name); struct submodule_entry *e = xmalloc(sizeof(*e)); hashmap_entry_init(e, hash); e->config = submodule; @@ -151,14 +152,14 @@ static void cache_add(struct submodule_cache *cache, } static const struct submodule *cache_lookup_path(struct submodule_cache *cache, - const unsigned char *gitmodules_sha1, const char *path) + const struct object_id *gitmodules_oid, const char *path) { struct submodule_entry *entry; - unsigned int hash = hash_sha1_string(gitmodules_sha1, path); + unsigned int hash = hash_oid_string(gitmodules_oid, path); struct submodule_entry key; struct submodule key_config; - hashcpy(key_config.gitmodules_sha1, gitmodules_sha1); + oidcpy(&key_config.gitmodules_oid, gitmodules_oid); key_config.path = path; hashmap_entry_init(&key, hash); @@ -171,14 +172,14 @@ static const struct submodule *cache_lookup_path(struct submodule_cache *cache, } static struct submodule *cache_lookup_name(struct submodule_cache *cache, - const unsigned char *gitmodules_sha1, const char *name) + const struct object_id *gitmodules_oid, const char *name) { struct submodule_entry *entry; - unsigned int hash = hash_sha1_string(gitmodules_sha1, name); + unsigned int hash = hash_oid_string(gitmodules_oid, name); struct submodule_entry key; struct submodule key_config; - hashcpy(key_config.gitmodules_sha1, gitmodules_sha1); + oidcpy(&key_config.gitmodules_oid, gitmodules_oid); key_config.name = name; hashmap_entry_init(&key, hash); @@ -238,12 +239,12 @@ static int name_and_item_from_var(const char *var, struct strbuf *name, } static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache, - const unsigned char *gitmodules_sha1, const char *name) + const struct object_id *gitmodules_oid, const char *name) { struct submodule *submodule; struct strbuf name_buf = STRBUF_INIT; - submodule = cache_lookup_name(cache, gitmodules_sha1, name); + submodule = cache_lookup_name(cache, gitmodules_oid, name); if (submodule) return submodule; @@ -261,7 +262,7 @@ static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache, submodule->branch = NULL; submodule->recommend_shallow = -1; - hashcpy(submodule->gitmodules_sha1, gitmodules_sha1); + oidcpy(&submodule->gitmodules_oid, gitmodules_oid); cache_add(cache, submodule); @@ -372,12 +373,12 @@ int parse_push_recurse_submodules_arg(const char *opt, const char *arg) return parse_push_recurse(opt, arg, 1); } -static void warn_multiple_config(const unsigned char *treeish_name, +static void warn_multiple_config(const struct object_id *treeish_name, const char *name, const char *option) { const char *commit_string = "WORKTREE"; if (treeish_name) - commit_string = sha1_to_hex(treeish_name); + commit_string = oid_to_hex(treeish_name); warning("%s:.gitmodules, multiple configurations found for " "'submodule.%s.%s'. Skipping second one!", commit_string, name, option); @@ -385,8 +386,8 @@ static void warn_multiple_config(const unsigned char *treeish_name, struct parse_config_parameter { struct submodule_cache *cache; - const unsigned char *treeish_name; - const unsigned char *gitmodules_sha1; + const struct object_id *treeish_name; + const struct object_id *gitmodules_oid; int overwrite; }; @@ -402,7 +403,7 @@ static int parse_config(const char *var, const char *value, void *data) return 0; submodule = lookup_or_create_by_name(me->cache, - me->gitmodules_sha1, + me->gitmodules_oid, name.buf); if (!strcmp(item.buf, "path")) { @@ -420,7 +421,7 @@ static int parse_config(const char *var, const char *value, void *data) } } else if (!strcmp(item.buf, "fetchrecursesubmodules")) { /* when parsing worktree configurations we can die early */ - int die_on_error = is_null_sha1(me->gitmodules_sha1); + int die_on_error = is_null_oid(me->gitmodules_oid); if (!me->overwrite && submodule->fetch_recurse != RECURSE_SUBMODULES_NONE) warn_multiple_config(me->treeish_name, submodule->name, @@ -542,34 +543,34 @@ static const struct submodule *config_from(struct submodule_cache *cache, switch (lookup_type) { case lookup_name: - submodule = cache_lookup_name(cache, oid.hash, key); + submodule = cache_lookup_name(cache, &oid, key); break; case lookup_path: - submodule = cache_lookup_path(cache, oid.hash, key); + submodule = cache_lookup_path(cache, &oid, key); break; } if (submodule) goto out; - config = read_sha1_file(oid.hash, &type, &config_size); + config = read_object_file(&oid, &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->hash; - parameter.gitmodules_sha1 = oid.hash; + parameter.treeish_name = treeish_name; + 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); switch (lookup_type) { case lookup_name: - return cache_lookup_name(cache, oid.hash, key); + return cache_lookup_name(cache, &oid, key); case lookup_path: - return cache_lookup_path(cache, oid.hash, key); + return cache_lookup_path(cache, &oid, key); default: return NULL; } @@ -591,6 +592,23 @@ 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) { + char *file = repo_worktree_path(repo, GITMODULES_FILE); + git_config_from_file(fn, file, data); + free(file); + } +} + static int gitmodules_cb(const char *var, const char *value, void *data) { struct repository *repo = data; @@ -598,7 +616,7 @@ static int gitmodules_cb(const char *var, const char *value, void *data) parameter.cache = repo->submodule_cache; parameter.treeish_name = NULL; - parameter.gitmodules_sha1 = null_sha1; + parameter.gitmodules_oid = &null_oid; parameter.overwrite = 1; return parse_config(var, value, ¶meter); @@ -608,19 +626,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 (repo_read_index(repo) < 0) + return; - if (!is_gitmodules_unmerged(repo->index)) - git_config_from_file(gitmodules_cb, gitmodules, repo); - - free(gitmodules); - } + if (!is_gitmodules_unmerged(repo->index)) + config_from_gitmodules(gitmodules_cb, repo, repo); repo->submodule_cache->gitmodules_read = 1; } @@ -650,31 +660,66 @@ static void gitmodules_read_check(struct repository *repo) repo_read_gitmodules(repo); } -const struct submodule *submodule_from_name(const struct object_id *treeish_name, +const struct submodule *submodule_from_name(struct repository *r, + 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); + gitmodules_read_check(r); + return config_from(r->submodule_cache, treeish_name, name, lookup_name); } -const struct submodule *submodule_from_path(const struct object_id *treeish_name, +const struct submodule *submodule_from_path(struct repository *r, + const struct object_id *treeish_name, const char *path) { - gitmodules_read_check(the_repository); - return config_from(the_repository->submodule_cache, treeish_name, path, lookup_path); + gitmodules_read_check(r); + return config_from(r->submodule_cache, treeish_name, path, lookup_path); +} + +void submodule_free(struct repository *r) +{ + if (r->submodule_cache) + submodule_cache_clear(r->submodule_cache); } -const struct submodule *submodule_from_cache(struct repository *repo, - const struct object_id *treeish_name, - const char *key) +struct fetch_config { + int *max_children; + int *recurse_submodules; +}; + +static int gitmodules_fetch_config(const char *var, const char *value, void *cb) { - gitmodules_read_check(repo); - return config_from(repo->submodule_cache, treeish_name, - key, lookup_path); + 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 submodule_free(void) +void update_clone_config_from_gitmodules(int *max_jobs) { - if (the_repository->submodule_cache) - submodule_cache_clear(the_repository->submodule_cache); + config_from_gitmodules(gitmodules_update_clone_config, the_repository, &max_jobs); } |