Merge branch 'ma/up-to-date'
[gitweb.git] / submodule-config.c
index bede338c8539f18081168bacd0b562a927e9532c..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)
@@ -238,7 +240,7 @@ static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache,
 static int parse_fetch_recurse(const char *opt, const char *arg,
                               int die_on_error)
 {
-       switch (git_config_maybe_bool(opt, arg)) {
+       switch (git_parse_maybe_bool(arg)) {
        case 1:
                return RECURSE_SUBMODULES_ON;
        case 0:
@@ -254,6 +256,14 @@ static int parse_fetch_recurse(const char *opt, const char *arg,
        }
 }
 
+int parse_submodule_fetchjobs(const char *var, const char *value)
+{
+       int fetchjobs = git_config_int(var, value);
+       if (fetchjobs < 0)
+               die(_("negative values not allowed for submodule.fetchjobs"));
+       return fetchjobs;
+}
+
 int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg)
 {
        return parse_fetch_recurse(opt, arg, 1);
@@ -283,7 +293,7 @@ int option_fetch_parse_recurse_submodules(const struct option *opt,
 static int parse_update_recurse(const char *opt, const char *arg,
                                int die_on_error)
 {
-       switch (git_config_maybe_bool(opt, arg)) {
+       switch (git_parse_maybe_bool(arg)) {
        case 1:
                return RECURSE_SUBMODULES_ON;
        case 0:
@@ -303,7 +313,7 @@ int parse_update_recurse_submodules_arg(const char *opt, const char *arg)
 static int parse_push_recurse(const char *opt, const char *arg,
                               int die_on_error)
 {
-       switch (git_config_maybe_bool(opt, arg)) {
+       switch (git_parse_maybe_bool(arg)) {
        case 1:
                /* There's no simple "on" value when pushing */
                if (die_on_error)
@@ -447,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;
 
@@ -550,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;
@@ -565,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)
+{
+       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)
 {
-       return submodule_config_option(the_repository, var, value);
+       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);
 }
 
@@ -588,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);
 }