Merge branch 'cb/xdiff-no-system-includes-in-dot-c' into maint
[gitweb.git] / submodule-config.c
index e04ba756d954e03f4c94785f260c2ac9af6a6f9b..4264ee216f49773c86e2e161d28ceec656a1273c 100644 (file)
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "dir.h"
 #include "repository.h"
 #include "config.h"
 #include "submodule-config.h"
@@ -280,7 +281,10 @@ static int parse_fetch_recurse(const char *opt, const char *arg,
        default:
                if (!strcmp(arg, "on-demand"))
                        return RECURSE_SUBMODULES_ON_DEMAND;
-
+               /*
+                * Please update $__git_fetch_recurse_submodules in
+                * git-completion.bash when you add new options.
+                */
                if (die_on_error)
                        die("bad %s argument: %s", opt, arg);
                else
@@ -361,6 +365,10 @@ static int parse_push_recurse(const char *opt, const char *arg,
                        return RECURSE_SUBMODULES_CHECK;
                else if (!strcmp(arg, "only"))
                        return RECURSE_SUBMODULES_ONLY;
+               /*
+                * Please update $__git_push_recurse_submodules in
+                * git-completion.bash when you add new modes.
+                */
                else if (die_on_error)
                        die("bad %s argument: %s", opt, arg);
                else
@@ -384,6 +392,12 @@ static void warn_multiple_config(const struct object_id *treeish_name,
                        commit_string, name, option);
 }
 
+static void warn_command_line_option(const char *var, const char *value)
+{
+       warning(_("ignoring '%s' which may be interpreted as"
+                 " a command-line option: %s"), var, value);
+}
+
 struct parse_config_parameter {
        struct submodule_cache *cache;
        const struct object_id *treeish_name;
@@ -409,6 +423,8 @@ static int parse_config(const char *var, const char *value, void *data)
        if (!strcmp(item.buf, "path")) {
                if (!value)
                        ret = config_error_nonbool(var);
+               else if (looks_like_command_line_option(value))
+                       warn_command_line_option(var, value);
                else if (!me->overwrite && submodule->path)
                        warn_multiple_config(me->treeish_name, submodule->name,
                                        "path");
@@ -449,6 +465,8 @@ static int parse_config(const char *var, const char *value, void *data)
        } else if (!strcmp(item.buf, "url")) {
                if (!value) {
                        ret = config_error_nonbool(var);
+               } else if (looks_like_command_line_option(value)) {
+                       warn_command_line_option(var, value);
                } else if (!me->overwrite && submodule->url) {
                        warn_multiple_config(me->treeish_name, submodule->name,
                                        "url");
@@ -603,8 +621,28 @@ static void submodule_cache_check_init(struct repository *repo)
 static void config_from_gitmodules(config_fn_t fn, struct repository *repo, void *data)
 {
        if (repo->worktree) {
-               char *file = repo_worktree_path(repo, GITMODULES_FILE);
-               git_config_from_file(fn, file, data);
+               struct git_config_source config_source = { 0 };
+               const struct config_options opts = { 0 };
+               struct object_id oid;
+               char *file;
+               char *oidstr = NULL;
+
+               file = repo_worktree_path(repo, GITMODULES_FILE);
+               if (file_exists(file)) {
+                       config_source.file = file;
+               } else if (repo_get_oid(repo, GITMODULES_INDEX, &oid) >= 0 ||
+                          repo_get_oid(repo, GITMODULES_HEAD, &oid) >= 0) {
+                       config_source.blob = oidstr = xstrdup(oid_to_hex(&oid));
+                       if (repo != the_repository)
+                               add_to_alternates_memory(repo->objects->odb->path);
+               } else {
+                       goto out;
+               }
+
+               config_with_options(fn, data, &config_source, &opts);
+
+out:
+               free(oidstr);
                free(file);
        }
 }
@@ -682,6 +720,43 @@ void submodule_free(struct repository *r)
                submodule_cache_clear(r->submodule_cache);
 }
 
+static int config_print_callback(const char *var, const char *value, void *cb_data)
+{
+       char *wanted_key = cb_data;
+
+       if (!strcmp(wanted_key, var))
+               printf("%s\n", value);
+
+       return 0;
+}
+
+int print_config_from_gitmodules(struct repository *repo, const char *key)
+{
+       int ret;
+       char *store_key;
+
+       ret = git_config_parse_key(key, &store_key, NULL);
+       if (ret < 0)
+               return CONFIG_INVALID_KEY;
+
+       config_from_gitmodules(config_print_callback, repo, store_key);
+
+       free(store_key);
+       return 0;
+}
+
+int config_set_in_gitmodules_file_gently(const char *key, const char *value)
+{
+       int ret;
+
+       ret = git_config_set_in_file_gently(GITMODULES_FILE, key, value);
+       if (ret < 0)
+               /* Maybe the user already did that, don't error out here */
+               warning(_("Could not update .gitmodules entry %s"), key);
+
+       return ret;
+}
+
 struct fetch_config {
        int *max_children;
        int *recurse_submodules;