summaryrefslogtreecommitdiff
path: root/builtin/submodule--helper.c
diff options
context:
space:
mode:
authorLibravatar Atharva Raykar <raykar.ath@gmail.com>2021-08-06 19:34:31 +0530
committerLibravatar Junio C Hamano <gitster@pobox.com>2021-08-10 10:57:57 -0700
commita452128a36cb73f5366c23eabe93c7edfa227866 (patch)
treeffad56bf1145c48e1bd64c73a2d642df972745ad /builtin/submodule--helper.c
parentsubmodule: drop unused sm_name parameter from show_fetch_remotes() (diff)
downloadtgif-a452128a36cb73f5366c23eabe93c7edfa227866.tar.xz
submodule--helper: introduce add-config subcommand
Add a new "add-config" subcommand to `git submodule--helper` with the goal of converting part of the shell code in git-submodule.sh related to `git submodule add` into C code. This new subcommand sets the configuration variables of a newly added submodule, by registering the url in local git config, as well as the submodule name and path in the .gitmodules file. It also sets 'submodule.<name>.active' to "true" if the submodule path has not already been covered by any pathspec specified in 'submodule.active'. This is meant to be a faithful conversion from shell to C, although we add comments to areas that could be improved in future patches, after the conversion has settled. Signed-off-by: Atharva Raykar <raykar.ath@gmail.com> Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Shourya Shukla <periperidip@gmail.com> Based-on-patch-by: Shourya Shukla <periperidip@gmail.com> Based-on-patch-by: Prathamesh Chavan <pc44800@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/submodule--helper.c')
-rw-r--r--builtin/submodule--helper.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index a592ecaec1..7c3ed74118 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2935,6 +2935,134 @@ static int add_clone(int argc, const char **argv, const char *prefix)
return 0;
}
+static int config_submodule_in_gitmodules(const char *name, const char *var, const char *value)
+{
+ char *key;
+ int ret;
+
+ if (!is_writing_gitmodules_ok())
+ die(_("please make sure that the .gitmodules file is in the working tree"));
+
+ key = xstrfmt("submodule.%s.%s", name, var);
+ ret = config_set_in_gitmodules_file_gently(key, value);
+ free(key);
+
+ return ret;
+}
+
+static void configure_added_submodule(struct add_data *add_data)
+{
+ char *key;
+ char *val = NULL;
+ struct child_process add_submod = CHILD_PROCESS_INIT;
+ struct child_process add_gitmodules = CHILD_PROCESS_INIT;
+
+ key = xstrfmt("submodule.%s.url", add_data->sm_name);
+ git_config_set_gently(key, add_data->realrepo);
+ free(key);
+
+ add_submod.git_cmd = 1;
+ strvec_pushl(&add_submod.args, "add",
+ "--no-warn-embedded-repo", NULL);
+ if (add_data->force)
+ strvec_push(&add_submod.args, "--force");
+ strvec_pushl(&add_submod.args, "--", add_data->sm_path, NULL);
+
+ if (run_command(&add_submod))
+ die(_("Failed to add submodule '%s'"), add_data->sm_path);
+
+ if (config_submodule_in_gitmodules(add_data->sm_name, "path", add_data->sm_path) ||
+ config_submodule_in_gitmodules(add_data->sm_name, "url", add_data->repo))
+ die(_("Failed to register submodule '%s'"), add_data->sm_path);
+
+ if (add_data->branch) {
+ if (config_submodule_in_gitmodules(add_data->sm_name,
+ "branch", add_data->branch))
+ die(_("Failed to register submodule '%s'"), add_data->sm_path);
+ }
+
+ add_gitmodules.git_cmd = 1;
+ strvec_pushl(&add_gitmodules.args,
+ "add", "--force", "--", ".gitmodules", NULL);
+
+ if (run_command(&add_gitmodules))
+ die(_("Failed to register submodule '%s'"), add_data->sm_path);
+
+ /*
+ * NEEDSWORK: In a multi-working-tree world this needs to be
+ * set in the per-worktree config.
+ */
+ /*
+ * NEEDSWORK: In the longer run, we need to get rid of this
+ * pattern of querying "submodule.active" before calling
+ * is_submodule_active(), since that function needs to find
+ * out the value of "submodule.active" again anyway.
+ */
+ if (!git_config_get_string("submodule.active", &val) && val) {
+ /*
+ * If the submodule being added isn't already covered by the
+ * current configured pathspec, set the submodule's active flag
+ */
+ if (!is_submodule_active(the_repository, add_data->sm_path)) {
+ key = xstrfmt("submodule.%s.active", add_data->sm_name);
+ git_config_set_gently(key, "true");
+ free(key);
+ }
+ } else {
+ key = xstrfmt("submodule.%s.active", add_data->sm_name);
+ git_config_set_gently(key, "true");
+ free(key);
+ }
+}
+
+static int add_config(int argc, const char **argv, const char *prefix)
+{
+ int force = 0;
+ struct add_data add_data = ADD_DATA_INIT;
+
+ struct option options[] = {
+ OPT_STRING('b', "branch", &add_data.branch,
+ N_("branch"),
+ N_("branch of repository to store in "
+ "the submodule configuration")),
+ OPT_STRING(0, "url", &add_data.repo,
+ N_("string"),
+ N_("url to clone submodule from")),
+ OPT_STRING(0, "resolved-url", &add_data.realrepo,
+ N_("string"),
+ N_("url to clone the submodule from, after it has "
+ "been dereferenced relative to parent's url, "
+ "in the case where <url> is a relative url")),
+ OPT_STRING(0, "path", &add_data.sm_path,
+ N_("path"),
+ N_("where the new submodule will be cloned to")),
+ OPT_STRING(0, "name", &add_data.sm_name,
+ N_("string"),
+ N_("name of the new submodule")),
+ OPT__FORCE(&force, N_("allow adding an otherwise ignored submodule path"),
+ PARSE_OPT_NOCOMPLETE),
+ OPT_END()
+ };
+
+ const char *const usage[] = {
+ N_("git submodule--helper add-config "
+ "[--force|-f] [--branch|-b <branch>] "
+ "--url <url> --resolved-url <resolved-url> "
+ "--path <path> --name <name>"),
+ NULL
+ };
+
+ argc = parse_options(argc, argv, prefix, options, usage, 0);
+
+ if (argc)
+ usage_with_options(usage, options);
+
+ add_data.force = !!force;
+ configure_added_submodule(&add_data);
+
+ return 0;
+}
+
#define SUPPORT_SUPER_PREFIX (1<<0)
struct cmd_struct {
@@ -2948,6 +3076,7 @@ static struct cmd_struct commands[] = {
{"name", module_name, 0},
{"clone", module_clone, 0},
{"add-clone", add_clone, 0},
+ {"add-config", add_config, 0},
{"update-module-mode", module_update_module_mode, 0},
{"update-clone", update_clone, 0},
{"ensure-core-worktree", ensure_core_worktree, 0},