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 <pclo...@gmail.com>
---
 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

Reply via email to