submodule-config: lazy-load a repository's .gitmodules file
authorBrandon Williams <bmwill@google.com>
Thu, 3 Aug 2017 18:19:58 +0000 (11:19 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 3 Aug 2017 20:11:01 +0000 (13:11 -0700)
In order to use the submodule-config subsystem, callers first need to
initialize it by calling 'repo_read_gitmodules()' or
'gitmodules_config()' (which just redirects to
'repo_read_gitmodules()'). There are a couple of callers who need to
load an explicit revision of the repository's .gitmodules file (grep) or
need to modify the .gitmodules file so they would need to load it before
modify the file (checkout), but the majority of callers are simply
reading the .gitmodules file present in the working tree. For the
common case it would be nice to avoid the boilerplate of initializing
the submodule-config system before using it, so instead let's perform
lazy-loading of the submodule-config system.

Remove the calls to reading the gitmodules file from ls-files to show
that lazy-loading the .gitmodules file works.

Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/ls-files.c
submodule-config.c
index d14612057e3e30818f18ab9fefa80805191a6e28..bd74ee07db4182801bd26f0a6f931882f0b310bc 100644 (file)
@@ -211,8 +211,6 @@ static void show_submodule(struct repository *superproject,
        if (repo_read_index(&submodule) < 0)
                die("index file corrupt");
 
-       repo_read_gitmodules(&submodule);
-
        show_files(&submodule, dir);
 
        repo_clear(&submodule);
@@ -611,9 +609,6 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
        if (require_work_tree && !is_inside_work_tree())
                setup_work_tree();
 
-       if (recurse_submodules)
-               repo_read_gitmodules(the_repository);
-
        if (recurse_submodules &&
            (show_stage || show_deleted || show_others || show_unmerged ||
             show_killed || show_modified || show_resolve_undo || with_tree))
index 86636654bda992d78f0d11cbc7687e9599bfa556..56d9d76d408d0bba967e5b8509f971e93a090b12 100644 (file)
@@ -18,6 +18,7 @@ struct submodule_cache {
        struct hashmap for_path;
        struct hashmap for_name;
        unsigned initialized:1;
+       unsigned gitmodules_read:1;
 };
 
 /*
@@ -93,6 +94,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)
@@ -557,8 +559,6 @@ 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;
@@ -569,6 +569,8 @@ static int gitmodules_cb(const char *var, const char *value, void *data)
 
 void repo_read_gitmodules(struct repository *repo)
 {
+       submodule_cache_check_init(repo);
+
        if (repo->worktree) {
                char *gitmodules;
 
@@ -582,6 +584,8 @@ void repo_read_gitmodules(struct repository *repo)
 
                free(gitmodules);
        }
+
+       repo->submodule_cache->gitmodules_read = 1;
 }
 
 void gitmodules_config_oid(const struct object_id *commit_oid)
@@ -589,24 +593,37 @@ 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)
 {
-       submodule_cache_check_init(the_repository);
+       gitmodules_read_check(the_repository);
        return config_from(the_repository->submodule_cache, treeish_name, name, lookup_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);
 }
 
@@ -614,7 +631,7 @@ const struct submodule *submodule_from_cache(struct repository *repo,
                                             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);
 }