submodule-config: lazy-load a repository's .gitmodules file

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>

Brandon Williams committed Aug 3, 2017 at 11:19 UTC ff6f1f564c48def1f8e1852826bab58af5044b06
2 files changed +22 -10
builtin/ls-files.c
-5
@@ -211,8 +211,6 @@ static void show_submodule(struct repository *superproject,
211 if (repo_read_index(&submodule) < 0)
212 die("index file corrupt");
213
214 - repo_read_gitmodules(&submodule);
215 -
214 show_files(&submodule, dir);
215
216 repo_clear(&submodule);
@@ -611,9 +609,6 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
609 if (require_work_tree && !is_inside_work_tree())
610 setup_work_tree();
611
614 - if (recurse_submodules)
615 - repo_read_gitmodules(the_repository);
616 -
612 if (recurse_submodules &&
613 (show_stage || show_deleted || show_others || show_unmerged ||
614 show_killed || show_modified || show_resolve_undo || with_tree))
submodule-config.c
+22 -5
@@ -18,6 +18,7 @@ struct submodule_cache {
18 struct hashmap for_path;
19 struct hashmap for_name;
20 unsigned initialized:1;
21 + unsigned gitmodules_read:1;
22 };
23
24 /*
@@ -93,6 +94,7 @@ static void submodule_cache_clear(struct submodule_cache *cache)
94 hashmap_free(&cache->for_path, 1);
95 hashmap_free(&cache->for_name, 1);
96 cache->initialized = 0;
97 + cache->gitmodules_read = 0;
98 }
99
100 void submodule_cache_free(struct submodule_cache *cache)
@@ -557,8 +559,6 @@ static int gitmodules_cb(const char *var, const char *value, void *data)
559 struct repository *repo = data;
560 struct parse_config_parameter parameter;
561
560 - submodule_cache_check_init(repo);
561 -
562 parameter.cache = repo->submodule_cache;
563 parameter.treeish_name = NULL;
564 parameter.gitmodules_sha1 = null_sha1;
@@ -569,6 +569,8 @@ static int gitmodules_cb(const char *var, const char *value, void *data)
569
570 void repo_read_gitmodules(struct repository *repo)
571 {
572 + submodule_cache_check_init(repo);
573 +
574 if (repo->worktree) {
575 char *gitmodules;
576
@@ -582,6 +584,8 @@ void repo_read_gitmodules(struct repository *repo)
584
585 free(gitmodules);
586 }
587 +
588 + repo->submodule_cache->gitmodules_read = 1;
589 }
590
591 void gitmodules_config_oid(const struct object_id *commit_oid)
@@ -589,24 +593,37 @@ void gitmodules_config_oid(const struct object_id *commit_oid)
593 struct strbuf rev = STRBUF_INIT;
594 struct object_id oid;
595
596 + submodule_cache_check_init(the_repository);
597 +
598 if (gitmodule_oid_from_commit(commit_oid, &oid, &rev)) {
599 git_config_from_blob_oid(gitmodules_cb, rev.buf,
600 &oid, the_repository);
601 }
602 strbuf_release(&rev);
603 +
604 + the_repository->submodule_cache->gitmodules_read = 1;
605 +}
606 +
607 +static void gitmodules_read_check(struct repository *repo)
608 +{
609 + submodule_cache_check_init(repo);
610 +
611 + /* read the repo's .gitmodules file if it hasn't been already */
612 + if (!repo->submodule_cache->gitmodules_read)
613 + repo_read_gitmodules(repo);
614 }
615
616 const struct submodule *submodule_from_name(const struct object_id *treeish_name,
617 const char *name)
618 {
602 - submodule_cache_check_init(the_repository);
619 + gitmodules_read_check(the_repository);
620 return config_from(the_repository->submodule_cache, treeish_name, name, lookup_name);
621 }
622
623 const struct submodule *submodule_from_path(const struct object_id *treeish_name,
624 const char *path)
625 {
609 - submodule_cache_check_init(the_repository);
626 + gitmodules_read_check(the_repository);
627 return config_from(the_repository->submodule_cache, treeish_name, path, lookup_path);
628 }
629
@@ -614,7 +631,7 @@ const struct submodule *submodule_from_cache(struct repository *repo,
631 const struct object_id *treeish_name,
632 const char *key)
633 {
617 - submodule_cache_check_init(repo);
634 + gitmodules_read_check(repo);
635 return config_from(repo->submodule_cache, treeish_name,
636 key, lookup_path);
637 }