Avoid direct access to $SUBMODULE/config and do it through repo_config_set() instead. Note that repo_submodule_init() cannot be used because this early in the submodule initialization process, we may fail to get and parse .gitmodules with submodule_from_path(). Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- builtin/submodule--helper.c | 24 +++++++----------------- config.c | 10 ++++++++++ config.h | 1 + repository.c | 21 ++++++++++++++------- repository.h | 4 ++++ 5 files changed, 36 insertions(+), 24 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 8943127ae7..b5d74cd415 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1366,11 +1366,11 @@ static int module_clone(int argc, const char **argv, const char *prefix) const char *name = NULL, *url = NULL, *depth = NULL; int quiet = 0; int progress = 0; - char *p, *path = NULL, *sm_gitdir; + char *path = NULL, *sm_gitdir; struct strbuf sb = STRBUF_INIT; struct string_list reference = STRING_LIST_INIT_NODUP; int dissociate = 0; - char *sm_alternate = NULL, *error_strategy = NULL; + struct repository subrepo; struct option module_clone_options[] = { OPT_STRING(0, "prefix", &prefix, @@ -1443,27 +1443,17 @@ static int module_clone(int argc, const char **argv, const char *prefix) connect_work_tree_and_git_dir(path, sm_gitdir, 0); - p = git_pathdup_submodule(path, "config"); - if (!p) - die(_("could not get submodule directory for '%s'"), path); + if (repo_submodule_init_by_name(&subrepo, the_repository, path, name)) + die(_("could not get a repository handle for submodule '%s'"), path); /* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */ - git_config_get_string("submodule.alternateLocation", &sm_alternate); - if (sm_alternate) - git_config_set_in_file(p, "submodule.alternateLocation", - sm_alternate); - git_config_get_string("submodule.alternateErrorStrategy", &error_strategy); - if (error_strategy) - git_config_set_in_file(p, "submodule.alternateErrorStrategy", - error_strategy); - - free(sm_alternate); - free(error_strategy); + repo_config_copy(&subrepo, the_repository, "submodule.alternateLocation"); + repo_config_copy(&subrepo, the_repository, "submodule.alternateErrorStrategy"); + repo_clear(&subrepo); strbuf_release(&sb); free(sm_gitdir); free(path); - free(p); return 0; } diff --git a/config.c b/config.c index 151d28664e..007436b382 100644 --- a/config.c +++ b/config.c @@ -2157,6 +2157,16 @@ void repo_config_set(struct repository *r, const char *key, const char *value) die(_("could not unset '%s'"), key); } +void repo_config_copy(struct repository *dst, struct repository *src, const char *key) +{ + char *value = NULL; + + repo_config_get_string(src, key, &value); + if (value) + repo_config_set(dst, key, value); + free(value); +} + int repo_config_set_worktree_gently(struct repository *r, const char *key, const char *value) { diff --git a/config.h b/config.h index 62204dc252..22edd96716 100644 --- a/config.h +++ b/config.h @@ -105,6 +105,7 @@ extern void git_config_set_in_file(const char *, const char *, const char *); extern int git_config_set_gently(const char *, const char *); extern int repo_config_set_gently(struct repository *, const char *, const char *); extern void repo_config_set(struct repository *, const char *, const char *); +extern void repo_config_copy(struct repository *dst, struct repository *src, const char *key); extern int repo_config_set_worktree_gently(struct repository *, const char *, const char *); extern void git_config_set(const char *, const char *); extern int git_config_parse_key(const char *, char **, int *); diff --git a/repository.c b/repository.c index 5dd1486718..f997bd1629 100644 --- a/repository.c +++ b/repository.c @@ -176,16 +176,23 @@ int repo_submodule_init(struct repository *submodule, const char *path) { const struct submodule *sub; + + sub = submodule_from_path(superproject, &null_oid, path); + if (!sub) + return -1; + return repo_submodule_init_by_name(submodule, superproject, + path, sub->name); +} + +int repo_submodule_init_by_name(struct repository *submodule, + struct repository *superproject, + const char *path, + const char *name) +{ struct strbuf gitdir = STRBUF_INIT; struct strbuf worktree = STRBUF_INIT; int ret = 0; - sub = submodule_from_path(superproject, &null_oid, path); - if (!sub) { - ret = -1; - goto out; - } - strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", path); strbuf_repo_worktree_path(&worktree, superproject, "%s", path); @@ -199,7 +206,7 @@ int repo_submodule_init(struct repository *submodule, */ strbuf_reset(&gitdir); strbuf_repo_git_path(&gitdir, superproject, - "modules/%s", sub->name); + "modules/%s", name); if (repo_init(submodule, gitdir.buf, NULL)) { ret = -1; diff --git a/repository.h b/repository.h index 9f16c42c1e..d3f0592471 100644 --- a/repository.h +++ b/repository.h @@ -119,6 +119,10 @@ int repo_init(struct repository *r, const char *gitdir, const char *worktree); int repo_submodule_init(struct repository *submodule, struct repository *superproject, const char *path); +int repo_submodule_init_by_name(struct repository *submodule, + struct repository *superproject, + const char *path, + const char *name); void repo_clear(struct repository *repo); /* -- 2.20.0.482.g66447595a7