builtin/describe.c: describe a blob
[gitweb.git] / submodule-config.c
index 0c839019e1dca2e30ac0113303d55b4387bbe96d..2aa8a1747f8586839aa3036fbbc59f6c716c6128 100644 (file)
@@ -18,6 +18,7 @@ struct submodule_cache {
        struct hashmap for_path;
        struct hashmap for_name;
        unsigned initialized:1;
+       unsigned gitmodules_read:1;
 };
 
 /*
@@ -99,6 +100,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)
@@ -455,9 +457,9 @@ static int parse_config(const char *var, const char *value, void *data)
        return ret;
 }
 
-int gitmodule_oid_from_commit(const struct object_id *treeish_name,
-                                     struct object_id *gitmodules_oid,
-                                     struct strbuf *rev)
+static int gitmodule_oid_from_commit(const struct object_id *treeish_name,
+                                    struct object_id *gitmodules_oid,
+                                    struct strbuf *rev)
 {
        int ret = 0;
 
@@ -558,13 +560,11 @@ static void submodule_cache_check_init(struct repository *repo)
        submodule_cache_init(repo->submodule_cache);
 }
 
-int submodule_config_option(struct repository *repo,
-                           const char *var, const char *value)
+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;
@@ -573,22 +573,63 @@ int submodule_config_option(struct repository *repo,
        return parse_config(var, value, &parameter);
 }
 
-int parse_submodule_config_option(const char *var, const char *value)
+void repo_read_gitmodules(struct repository *repo)
 {
-       return submodule_config_option(the_repository, var, value);
+       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 (!is_gitmodules_unmerged(repo->index))
+                       git_config_from_file(gitmodules_cb, gitmodules, repo);
+
+               free(gitmodules);
+       }
+
+       repo->submodule_cache->gitmodules_read = 1;
+}
+
+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);
 }
 
@@ -596,7 +637,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);
 }