From: Atharva Raykar <raykar.ath@gmail.com>
To: git@vger.kernel.org
Cc: christian.couder@gmail.com, emilyshaffer@google.com,
gitster@pobox.com, jrnieder@gmail.com,
kaartic.sivaraam@gmail.com, pc44800@gmail.com,
periperidip@gmail.com, avarab@gmail.com,
Atharva Raykar <raykar.ath@gmail.com>
Subject: [PATCH 06/13] submodule: move core cmd_update() logic to C
Date: Tue, 7 Sep 2021 17:29:25 +0530 [thread overview]
Message-ID: <20210907115932.36068-7-raykar.ath@gmail.com> (raw)
In-Reply-To: <20210907115932.36068-1-raykar.ath@gmail.com>
This patch completes the conversion past the flag parsing of
`submodule update` by introducing a helper subcommand called
`submodule--helper update`. The behaviour of `submodule update` should
remain the same after this patch.
We add more fields to the `struct update_data` that are required by
`struct submodule_update_clone` to be able to perform a clone, when that
is needed to be done.
Recursing on a submodule is done by calling a subprocess that launches
`submodule--helper update`, with a modified `--recursive-prefix` and
`--prefix` parameter.
We also introduce `update_submodules()` and `update_submodule()` which
are quite similar to `update_clone_submodules()` and
`update_clone_submodule()`, and will supersede them.
When the `--init` flag is passed to the subcommand, we do not spawn a
new subprocess and call `submodule--helper init` on the submodule paths,
because the Git machinery is not able to pick up the configuration
changes introduced by that init call[1]. So we instead run the
`init_submodule_cb()` callback over each submodule directly.
This introduces another problem, because there is no mechanism to pass
the superproject path prefix (ie, `--super-prefix`) without starting a
new git process. This field is required for obtaining the display path
for that is used by the command's output messages. So let's add a field
into the `init_cb` struct that lets us pass this information to
`init_submodule()`, which will now also take an explicit 'superprefix'
argument.
[1] https://lore.kernel.org/git/CAP8UFD0NCQ5w_3GtT_xHr35i7h8BuLX4UcHNY6VHPGREmDVObA@mail.gmail.com/
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Shourya Shukla <periperidip@gmail.com>
Signed-off-by: Atharva Raykar <raykar.ath@gmail.com>
---
builtin/submodule--helper.c | 502 ++++++++++++++++++++++++++++++------
git-submodule.sh | 131 +---------
2 files changed, 430 insertions(+), 203 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 10de01a1f7..2cccb9a9ab 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -634,18 +634,22 @@ static char *compute_submodule_clone_url(const char *rel_url)
struct init_cb {
const char *prefix;
+ const char *superprefix;
unsigned int flags;
};
-#define INIT_CB_INIT { NULL, 0 }
+#define INIT_CB_INIT { NULL, NULL, 0 }
static void init_submodule(const char *path, const char *prefix,
- unsigned int flags)
+ const char *superprefix, unsigned int flags)
{
const struct submodule *sub;
struct strbuf sb = STRBUF_INIT;
char *upd = NULL, *url = NULL, *displaypath;
- displaypath = get_submodule_displaypath(path, prefix);
+ /* try superprefix from the environment, if it is not passed explicitly */
+ if (!superprefix)
+ superprefix = get_super_prefix();
+ displaypath = do_get_submodule_displaypath(path, prefix, superprefix);
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -719,7 +723,7 @@ static void init_submodule(const char *path, const char *prefix,
static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data)
{
struct init_cb *info = cb_data;
- init_submodule(list_item->name, info->prefix, info->flags);
+ init_submodule(list_item->name, info->prefix, info->superprefix, info->flags);
}
static int module_init(int argc, const char **argv, const char *prefix)
@@ -2039,7 +2043,6 @@ struct submodule_update_clone {
const char *prefix;
int single_branch;
- /* to be consumed by git-submodule.sh */
struct update_clone_data *update_clone;
int update_clone_nr; int update_clone_alloc;
@@ -2062,19 +2065,63 @@ struct submodule_update_clone {
}
struct update_data {
+ const char *prefix;
const char *recursive_prefix;
const char *sm_path;
const char *displaypath;
struct object_id oid;
struct object_id suboid;
- struct submodule_update_strategy update_strategy;
+ int max_jobs;
int depth;
+ int recommend_shallow;
+ int single_branch;
+ unsigned int init: 1;
unsigned int force: 1;
unsigned int quiet: 1;
unsigned int nofetch: 1;
- unsigned int just_cloned: 1;
+ unsigned int remote: 1;
+ unsigned int recursive: 1;
+ unsigned int progress: 1;
+ unsigned int dissociate: 1;
+ unsigned int require_init: 1;
+ unsigned warn_if_uninitialized : 1;
+ unsigned int just_cloned : 1;
+ struct submodule_update_strategy update_strategy;
+ struct string_list references;
+ struct module_list list;
};
-#define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT }
+#define UPDATE_DATA_INIT { \
+ .list = MODULE_LIST_INIT, \
+ .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \
+ .recommend_shallow = -1, \
+ .references = STRING_LIST_INIT_DUP, \
+ .single_branch = -1, \
+ .max_jobs = 1, \
+}
+
+static void update_clone_from_update_data(struct submodule_update_clone *suc,
+ struct update_data *update_data)
+{
+ suc->prefix = update_data->prefix;
+ suc->recursive_prefix = update_data->recursive_prefix;
+ suc->max_jobs = update_data->max_jobs;
+ suc->progress = update_data->progress;
+ suc->quiet = update_data->quiet;
+ suc->dissociate = update_data->dissociate;
+ suc->require_init = update_data->require_init;
+ suc->single_branch = update_data->single_branch;
+ suc->warn_if_uninitialized = update_data->warn_if_uninitialized;
+ suc->list = update_data->list;
+ suc->update = update_data->update_strategy;
+ suc->recommend_shallow = update_data->recommend_shallow;
+ if (update_data->depth)
+ suc->depth = xstrfmt("--depth=%d", update_data->depth);
+ if (update_data->references.nr) {
+ struct string_list_item *item;
+ for_each_string_list_item(item, &update_data->references)
+ string_list_append(&suc->references, item->string);
+ }
+}
static void next_submodule_warn_missing(struct submodule_update_clone *suc,
struct strbuf *out, const char *displaypath)
@@ -2369,111 +2416,113 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str
return run_command(&cp);
}
-static int run_update_command(struct update_data *ud, int subforce)
+static int run_update_command(struct update_data *ud, int subforce, struct string_list *err)
{
- struct strvec args = STRVEC_INIT;
- struct strvec child_env = STRVEC_INIT;
+ struct child_process cp = CHILD_PROCESS_INIT;
char *oid = oid_to_hex(&ud->oid);
+ struct strbuf out = STRBUF_INIT;
int must_die_on_failure = 0;
- int git_cmd;
+ struct submodule_update_strategy strategy = SUBMODULE_UPDATE_STRATEGY_INIT;
- switch (ud->update_strategy.type) {
+ if (ud->update_strategy.type == SM_UPDATE_UNSPECIFIED || ud->just_cloned)
+ determine_submodule_update_strategy(the_repository, ud->just_cloned,
+ ud->sm_path, NULL, &strategy);
+ else
+ strategy = ud->update_strategy;
+
+ cp.dir = xstrdup(ud->sm_path);
+ switch (strategy.type) {
case SM_UPDATE_CHECKOUT:
- git_cmd = 1;
- strvec_pushl(&args, "checkout", "-q", NULL);
+ cp.git_cmd = 1;
+ strvec_pushl(&cp.args, "checkout", "-q", NULL);
if (subforce)
- strvec_push(&args, "-f");
+ strvec_push(&cp.args, "-f");
break;
case SM_UPDATE_REBASE:
- git_cmd = 1;
- strvec_push(&args, "rebase");
+ cp.git_cmd = 1;
+ strvec_push(&cp.args, "rebase");
if (ud->quiet)
- strvec_push(&args, "--quiet");
+ strvec_push(&cp.args, "--quiet");
must_die_on_failure = 1;
break;
case SM_UPDATE_MERGE:
- git_cmd = 1;
- strvec_push(&args, "merge");
+ cp.git_cmd = 1;
+ strvec_push(&cp.args, "merge");
if (ud->quiet)
- strvec_push(&args, "--quiet");
+ strvec_push(&cp.args, "--quiet");
must_die_on_failure = 1;
break;
case SM_UPDATE_COMMAND:
- git_cmd = 0;
- strvec_push(&args, ud->update_strategy.command);
+ cp.git_cmd = 0;
+ cp.use_shell = 1;
+ strvec_push(&cp.args, strategy.command);
must_die_on_failure = 1;
break;
default:
BUG("unexpected update strategy type: %s",
- submodule_strategy_to_string(&ud->update_strategy));
+ submodule_strategy_to_string(&strategy));
}
- strvec_push(&args, oid);
+ strvec_push(&cp.args, oid);
- prepare_submodule_repo_env(&child_env);
- if (run_command_v_opt_cd_env(args.v, git_cmd ? RUN_GIT_CMD : RUN_USING_SHELL,
- ud->sm_path, child_env.v)) {
- switch (ud->update_strategy.type) {
- case SM_UPDATE_CHECKOUT:
- printf(_("Unable to checkout '%s' in submodule path '%s'"),
- oid, ud->displaypath);
- break;
- case SM_UPDATE_REBASE:
- printf(_("Unable to rebase '%s' in submodule path '%s'"),
- oid, ud->displaypath);
- break;
- case SM_UPDATE_MERGE:
- printf(_("Unable to merge '%s' in submodule path '%s'"),
- oid, ud->displaypath);
- break;
- case SM_UPDATE_COMMAND:
- printf(_("Execution of '%s %s' failed in submodule path '%s'"),
- ud->update_strategy.command, oid, ud->displaypath);
- break;
- default:
- BUG("unexpected update strategy type: %s",
- submodule_strategy_to_string(&ud->update_strategy));
+ prepare_submodule_repo_env(&cp.env_array);
+ if (capture_command(&cp, &out, 0)) {
+ if (must_die_on_failure) {
+ switch (strategy.type) {
+ case SM_UPDATE_CHECKOUT:
+ die(_("Unable to checkout '%s' in submodule path '%s'"),
+ oid, ud->displaypath);
+ break;
+ case SM_UPDATE_REBASE:
+ die(_("Unable to rebase '%s' in submodule path '%s'"),
+ oid, ud->displaypath);
+ break;
+ case SM_UPDATE_MERGE:
+ die(_("Unable to merge '%s' in submodule path '%s'"),
+ oid, ud->displaypath);
+ break;
+ case SM_UPDATE_COMMAND:
+ die(_("Execution of '%s %s' failed in submodule path '%s'"),
+ strategy.command, oid, ud->displaypath);
+ break;
+ default:
+ BUG("unexpected update strategy type: %s",
+ submodule_strategy_to_string(&strategy));
+ }
}
- /*
- * NEEDSWORK: We are currently printing to stdout with error
- * return so that the shell caller handles the error output
- * properly. Once we start handling the error messages within
- * C, we should use die() instead.
- */
- if (must_die_on_failure)
- return 2;
- /*
- * This signifies to the caller in shell that the command
- * failed without dying
- */
+
+ /* the command failed, but update must continue */
+ string_list_append(err, out.buf);
return 1;
}
- switch (ud->update_strategy.type) {
- case SM_UPDATE_CHECKOUT:
- printf(_("Submodule path '%s': checked out '%s'\n"),
- ud->displaypath, oid);
- break;
- case SM_UPDATE_REBASE:
- printf(_("Submodule path '%s': rebased into '%s'\n"),
- ud->displaypath, oid);
- break;
- case SM_UPDATE_MERGE:
- printf(_("Submodule path '%s': merged in '%s'\n"),
- ud->displaypath, oid);
- break;
- case SM_UPDATE_COMMAND:
- printf(_("Submodule path '%s': '%s %s'\n"),
- ud->displaypath, ud->update_strategy.command, oid);
- break;
- default:
- BUG("unexpected update strategy type: %s",
- submodule_strategy_to_string(&ud->update_strategy));
+ if (!ud->quiet) {
+ switch (strategy.type) {
+ case SM_UPDATE_CHECKOUT:
+ printf(_("Submodule path '%s': checked out '%s'\n"),
+ ud->displaypath, oid);
+ break;
+ case SM_UPDATE_REBASE:
+ printf(_("Submodule path '%s': rebased into '%s'\n"),
+ ud->displaypath, oid);
+ break;
+ case SM_UPDATE_MERGE:
+ printf(_("Submodule path '%s': merged in '%s'\n"),
+ ud->displaypath, oid);
+ break;
+ case SM_UPDATE_COMMAND:
+ printf(_("Submodule path '%s': '%s %s'\n"),
+ ud->displaypath, strategy.command, oid);
+ break;
+ default:
+ BUG("unexpected update strategy type: %s",
+ submodule_strategy_to_string(&strategy));
+ }
}
return 0;
}
-static int do_run_update_procedure(struct update_data *ud)
+static int do_run_update_procedure(struct update_data *ud, struct string_list *err)
{
int subforce = is_null_oid(&ud->suboid) || ud->force;
@@ -2500,7 +2549,7 @@ static int do_run_update_procedure(struct update_data *ud)
ud->displaypath, oid_to_hex(&ud->oid));
}
- return run_update_command(ud, subforce);
+ return run_update_command(ud, subforce, err);
}
static void update_clone_submodule(struct update_clone_data *ucd)
@@ -2605,6 +2654,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)
int force = 0, quiet = 0, nofetch = 0, just_cloned = 0;
char *prefixed_path, *update = NULL;
struct update_data update_data = UPDATE_DATA_INIT;
+ struct string_list err = STRING_LIST_INIT_DUP;
struct option options[] = {
OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")),
@@ -2662,7 +2712,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)
free(prefixed_path);
if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force)
- return do_run_update_procedure(&update_data);
+ return do_run_update_procedure(&update_data, &err);
return 3;
}
@@ -3038,6 +3088,288 @@ static int module_set_branch(int argc, const char **argv, const char *prefix)
return !!ret;
}
+static void update_data_to_args(struct update_data *update_data, struct strvec *args)
+{
+ const char *update = submodule_strategy_to_string(&update_data->update_strategy);
+
+ strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
+ strvec_pushf(args, "--jobs=%d", update_data->max_jobs);
+ if (update_data->prefix)
+ strvec_pushl(args, "--prefix", update_data->prefix, NULL);
+ if (update_data->recursive_prefix)
+ strvec_pushl(args, "--recursive-prefix",
+ update_data->recursive_prefix, NULL);
+ if (update_data->quiet)
+ strvec_push(args, "--quiet");
+ if (update_data->force)
+ strvec_push(args, "--force");
+ if (update_data->init)
+ strvec_push(args, "--init");
+ if (update_data->remote)
+ strvec_push(args, "--remote");
+ if (update_data->nofetch)
+ strvec_push(args, "--no-fetch");
+ if (update_data->dissociate)
+ strvec_push(args, "--dissociate");
+ if (update_data->progress)
+ strvec_push(args, "--progress");
+ if (update_data->require_init)
+ strvec_push(args, "--require-init");
+ if (update_data->depth)
+ strvec_pushf(args, "--depth=%d", update_data->depth);
+ if (update)
+ strvec_pushl(args, "--update", update, NULL);
+ if (update_data->references.nr) {
+ struct string_list_item *item;
+ for_each_string_list_item(item, &update_data->references)
+ strvec_pushl(args, "--reference", item->string, NULL);
+ }
+ if (update_data->recommend_shallow == 0)
+ strvec_push(args, "--no-recommend-shallow");
+ else if (update_data->recommend_shallow == 1)
+ strvec_push(args, "--recommend-shallow");
+ if (update_data->single_branch >= 0)
+ strvec_push(args, "--single-branch");
+}
+
+static int update_submodule(struct update_data *update_data)
+{
+ char *prefixed_path;
+ struct string_list err = STRING_LIST_INIT_DUP;
+
+ do_ensure_core_worktree(update_data->sm_path);
+
+ if (update_data->recursive_prefix)
+ prefixed_path = xstrfmt("%s%s", update_data->recursive_prefix,
+ update_data->sm_path);
+ else
+ prefixed_path = xstrdup(update_data->sm_path);
+
+ update_data->displaypath = get_submodule_displaypath(prefixed_path,
+ update_data->prefix);
+ free(prefixed_path);
+
+ if (update_data->just_cloned) {
+ oidcpy(&update_data->suboid, null_oid());
+ } else {
+ if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid))
+ die(_("Unable to find current revision in submodule path '%s'"),
+ update_data->displaypath);
+ }
+
+ if (update_data->remote) {
+ char *remote_name = get_default_remote_submodule(update_data->sm_path);
+ const char *branch = remote_submodule_branch(update_data->sm_path);
+ char *remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch);
+
+ if (!update_data->nofetch) {
+ if(fetch_in_submodule(update_data->sm_path, update_data->depth,
+ 0, NULL))
+ die(_("Unable to fetch in submodule path '%s'"),
+ update_data->sm_path);
+ }
+
+ if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid))
+ die(_("Unable to find %s revision in submodule path '%s'"),
+ remote_ref, update_data->sm_path);
+
+ free(remote_ref);
+ }
+
+ if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)
+ if (do_run_update_procedure(update_data, &err))
+ return 1;
+
+ if (update_data->recursive) {
+ int res;
+ struct child_process cp = CHILD_PROCESS_INIT;
+ struct update_data next = *update_data;
+ char *die_msg = xstrfmt(_("Failed to recurse into submodule path '%s'"),
+ update_data->displaypath);
+
+ if (update_data->recursive_prefix)
+ prefixed_path = xstrfmt("%s%s/", update_data->recursive_prefix,
+ update_data->sm_path);
+ else
+ prefixed_path = xstrfmt("%s/", update_data->sm_path);
+
+ next.recursive_prefix = get_submodule_displaypath(prefixed_path,
+ update_data->prefix);
+ next.prefix = NULL;
+ oidcpy(&next.oid, null_oid());
+ oidcpy(&next.suboid, null_oid());
+
+ cp.dir = update_data->sm_path;
+ cp.git_cmd = 1;
+ prepare_submodule_repo_env(&cp.env_array);
+ update_data_to_args(&next, &cp.args);
+
+ /* die() if child process die()'d */
+ if ((res = run_command(&cp)) == 128)
+ die("%s", die_msg);
+ if (res)
+ string_list_append(&err, die_msg);
+
+ free(die_msg);
+ }
+
+ if (err.nr) {
+ struct string_list_item *item;
+ for_each_string_list_item(item, &err)
+ fputs(item->string, stderr);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int update_submodules(struct update_data *update_data)
+{
+ int i, res = 0;
+ struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT;
+
+ update_clone_from_update_data(&suc, update_data);
+ run_processes_parallel_tr2(suc.max_jobs, update_clone_get_next_task,
+ update_clone_start_failure,
+ update_clone_task_finished, &suc, "submodule",
+ "parallel/update");
+
+ /*
+ * We saved the output and put it out all at once now.
+ * That means:
+ * - the listener does not have to interleave their (checkout)
+ * work with our fetching. The writes involved in a
+ * checkout involve more straightforward sequential I/O.
+ * - the listener can avoid doing any work if fetching failed.
+ */
+ if (suc.quickstop)
+ return 1;
+
+ for (i = 0; i < suc.update_clone_nr; i++) {
+ struct update_clone_data ucd = suc.update_clone[i];
+
+ oidcpy(&update_data->oid, &ucd.oid);
+ update_data->just_cloned = ucd.just_cloned;
+ update_data->sm_path = ucd.sub->path;
+
+ if (update_submodule(update_data))
+ res = 1;
+ }
+
+ return res;
+}
+
+static int module_update(int argc, const char **argv, const char *prefix)
+{
+ int init = 0, force = 0, quiet = 0, nofetch = 0;
+ int remote = 0, recursive = 0, dissociate = 0;
+ int progress = 0, require_init = 0;
+ const char *update = NULL;
+ struct pathspec pathspec;
+ struct update_data update_data = UPDATE_DATA_INIT;
+
+ struct option module_update_clone_options[] = {
+ OPT__FORCE(&force, N_("force checkout updates"), 0),
+ OPT_BOOL(0, "init", &init,
+ N_("initialize uninitialized submodules before update")),
+ OPT_BOOL(0, "remote", &remote,
+ N_("use SHA-1 of submodule's remote tracking branch")),
+ OPT_BOOL(0, "recursive", &recursive,
+ N_("traverse submodules recursively")),
+ OPT_BOOL('N', "no-fetch", &nofetch,
+ N_("don't fetch new objects from the remote site")),
+ OPT_STRING(0, "prefix", &prefix,
+ N_("path"),
+ N_("path into the working tree")),
+ OPT_STRING(0, "recursive-prefix", &update_data.recursive_prefix,
+ N_("path"),
+ N_("path into the working tree, across nested "
+ "submodule boundaries")),
+ OPT_STRING(0, "update", &update,
+ N_("string"),
+ N_("rebase, merge, checkout or none")),
+ OPT_STRING_LIST(0, "reference", &update_data.references, N_("repo"),
+ N_("reference repository")),
+ OPT_BOOL(0, "dissociate", &dissociate,
+ N_("use --reference only while cloning")),
+ OPT_INTEGER(0, "depth", &update_data.depth,
+ N_("create a shallow clone truncated to the "
+ "specified number of revisions")),
+ OPT_INTEGER('j', "jobs", &update_data.max_jobs,
+ N_("parallel jobs")),
+ OPT_BOOL(0, "recommend-shallow", &update_data.recommend_shallow,
+ N_("whether the initial clone should follow the shallow recommendation")),
+ OPT__QUIET(&quiet, N_("don't print cloning progress")),
+ OPT_BOOL(0, "progress", &progress,
+ N_("force cloning progress")),
+ OPT_BOOL(0, "require-init", &require_init,
+ N_("disallow cloning into non-empty directory")),
+ OPT_BOOL(0, "single-branch", &update_data.single_branch,
+ N_("clone only one branch, HEAD or --branch")),
+ OPT_END()
+ };
+
+ const char *const git_submodule_helper_usage[] = {
+ N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"),
+ NULL
+ };
+
+ update_clone_config_from_gitmodules(&update_data.max_jobs);
+ git_config(git_update_clone_config, &update_data.max_jobs);
+
+ argc = parse_options(argc, argv, prefix, module_update_clone_options,
+ git_submodule_helper_usage, 0);
+ update_data.prefix = prefix;
+
+ update_data.force = !!force;
+ update_data.quiet = !!quiet;
+ update_data.nofetch = !!nofetch;
+ update_data.init = !!init;
+ update_data.require_init = !!require_init;
+ update_data.remote = !!remote;
+ update_data.recursive = !!recursive;
+ update_data.progress = !!progress;
+ update_data.dissociate = !!dissociate;
+ oidcpy(&update_data.oid, null_oid());
+ oidcpy(&update_data.suboid, null_oid());
+
+ if (update)
+ if (parse_submodule_update_strategy(update,
+ &update_data.update_strategy) < 0)
+ die(_("bad value for update parameter"));
+
+ if (module_list_compute(argc, argv, prefix, &pathspec, &update_data.list) < 0)
+ return 1;
+
+ if (pathspec.nr)
+ update_data.warn_if_uninitialized = 1;
+
+ if (update_data.init) {
+ struct module_list list = MODULE_LIST_INIT;
+ struct init_cb info = INIT_CB_INIT;
+
+ if (module_list_compute(argc, argv, update_data.prefix,
+ &pathspec, &list) < 0)
+ return 1;
+
+ /*
+ * If there are no path args and submodule.active is set then,
+ * by default, only initialize 'active' modules.
+ */
+ if (!argc && git_config_get_value_multi("submodule.active"))
+ module_list_active(&list);
+
+ info.prefix = update_data.prefix;
+ info.superprefix = update_data.recursive_prefix;
+ if (update_data.quiet)
+ info.flags |= OPT_QUIET;
+
+ for_each_listed_submodule(&list, init_submodule_cb, &info);
+ }
+
+ return update_submodules(&update_data);
+}
+
struct add_data {
const char *prefix;
const char *branch;
@@ -3213,6 +3545,7 @@ static int add_clone(int argc, const char **argv, const char *prefix)
return 0;
}
+
#define SUPPORT_SUPER_PREFIX (1<<0)
struct cmd_struct {
@@ -3226,6 +3559,7 @@ static struct cmd_struct commands[] = {
{"name", module_name, 0},
{"clone", module_clone, 0},
{"add-clone", add_clone, 0},
+ {"update", module_update, 0},
{"update-module-mode", module_update_module_mode, 0},
{"update-clone", update_clone, 0},
{"run-update-procedure", run_update_procedure, 0},
diff --git a/git-submodule.sh b/git-submodule.sh
index f703cddce8..4e21d9715c 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -484,133 +484,26 @@ cmd_update()
shift
done
- if test -n "$init"
- then
- cmd_init "--" "$@" || return
- fi
-
- {
- git submodule--helper update-clone ${GIT_QUIET:+--quiet} \
- ${progress:+"--progress"} \
+ git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper update \
+ ${GIT_QUIET:+--quiet} \
+ ${force:+--force} \
+ ${progress:+--progress} \
+ ${dissociate:+--dissociate} \
+ ${remote:+--remote} \
+ ${recursive:+--recursive} \
+ ${init:+--init} \
+ ${require_init:+--require-init} \
+ ${nofetch:+--no-fetch} \
${wt_prefix:+--prefix "$wt_prefix"} \
${prefix:+--recursive-prefix "$prefix"} \
${update:+--update "$update"} \
${reference:+"$reference"} \
- ${dissociate:+"--dissociate"} \
- ${depth:+--depth "$depth"} \
- ${require_init:+--require-init} \
+ ${depth:+"$depth"} \
$single_branch \
$recommend_shallow \
$jobs \
-- \
- "$@" || echo "#unmatched" $?
- } | {
- err=
- while read -r quickabort sha1 just_cloned sm_path
- do
- die_if_unmatched "$quickabort" "$sha1"
-
- git submodule--helper ensure-core-worktree "$sm_path" || exit 1
-
- displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
-
- if test $just_cloned -eq 1
- then
- subsha1=
- else
- just_cloned=
- subsha1=$(sanitize_submodule_env; cd "$sm_path" &&
- git rev-parse --verify HEAD) ||
- die "fatal: $(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")"
- fi
-
- if test -n "$remote"
- then
- branch=$(git submodule--helper remote-branch "$sm_path")
- if test -z "$nofetch"
- then
- # Fetch remote before determining tracking $sha1
- fetch_in_submodule "$sm_path" $depth ||
- die "fatal: $(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
- fi
- remote_name=$(sanitize_submodule_env; cd "$sm_path" && git submodule--helper print-default-remote)
- sha1=$(sanitize_submodule_env; cd "$sm_path" &&
- git rev-parse --verify "${remote_name}/${branch}") ||
- die "fatal: $(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
- fi
-
- out=$(git submodule--helper run-update-procedure \
- ${wt_prefix:+--prefix "$wt_prefix"} \
- ${GIT_QUIET:+--quiet} \
- ${force:+--force} \
- ${just_cloned:+--just-cloned} \
- ${nofetch:+--no-fetch} \
- ${depth:+"$depth"} \
- ${update:+--update "$update"} \
- ${prefix:+--recursive-prefix "$prefix"} \
- ${sha1:+--oid "$sha1"} \
- ${subsha1:+--suboid "$subsha1"} \
- "--" \
- "$sm_path")
-
- # exit codes for run-update-procedure:
- # 0: update was successful, say command output
- # 1: update procedure failed, but should not die
- # 2 or 128: subcommand died during execution
- # 3: no update procedure was run
- res="$?"
- case $res in
- 0)
- say "$out"
- ;;
- 1)
- err="${err};fatal: $out"
- continue
- ;;
- 2|128)
- die_with_status $res "fatal: $out"
- ;;
- esac
-
- if test -n "$recursive"
- then
- (
- prefix=$(git submodule--helper relative-path "$prefix$sm_path/" "$wt_prefix")
- wt_prefix=
- sanitize_submodule_env
- cd "$sm_path" &&
- eval cmd_update
- )
- res=$?
- if test $res -gt 0
- then
- die_msg="fatal: $(eval_gettext "Failed to recurse into submodule path '\$displaypath'")"
- if test $res -ne 2
- then
- err="${err};$die_msg"
- continue
- else
- die_with_status $res "$die_msg"
- fi
- fi
- fi
- done
-
- if test -n "$err"
- then
- OIFS=$IFS
- IFS=';'
- for e in $err
- do
- if test -n "$e"
- then
- echo >&2 "$e"
- fi
- done
- IFS=$OIFS
- exit 1
- fi
- }
+ "$@"
}
#
--
2.32.0
next prev parent reply other threads:[~2021-09-07 12:00 UTC|newest]
Thread overview: 142+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-07 11:59 [PATCH 00/13] submodule: convert the rest of 'update' to C Atharva Raykar
2021-09-07 11:59 ` [PATCH 01/13] submodule--helper: split up ensure_core_worktree() Atharva Raykar
2021-09-07 11:59 ` [PATCH 02/13] submodule--helper: get remote names from any repository Atharva Raykar
2021-09-07 12:37 ` Ævar Arnfjörð Bjarmason
2021-09-07 13:33 ` Atharva Raykar
2021-09-07 11:59 ` [PATCH 03/13] submodule--helper: introduce get_default_remote_submodule() Atharva Raykar
2021-09-07 11:59 ` [PATCH 04/13] submodule--helper: rename helpers for update-clone Atharva Raykar
2021-09-07 11:59 ` [PATCH 05/13] submodule--helper: refactor get_submodule_displaypath() Atharva Raykar
2021-09-07 11:59 ` Atharva Raykar [this message]
2021-09-07 12:40 ` [PATCH 06/13] submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason
2021-09-07 11:59 ` [PATCH 07/13] submodule: remove fetch_in_submodule shell function Atharva Raykar
2021-09-07 12:44 ` Ævar Arnfjörð Bjarmason
2021-09-07 11:59 ` [PATCH 08/13] submodule--helper: remove update-clone subcommand Atharva Raykar
2021-09-07 12:46 ` Ævar Arnfjörð Bjarmason
2021-09-07 11:59 ` [PATCH 09/13] submodule--helper: remove update-module-mode subcommand Atharva Raykar
2021-09-07 12:49 ` Ævar Arnfjörð Bjarmason
2021-09-07 13:50 ` Atharva Raykar
2021-09-07 11:59 ` [PATCH 10/13] submodule--helper: remove shell interface to ensure_core_worktree() Atharva Raykar
2021-09-07 11:59 ` [PATCH 11/13] submodule--helper: remove print-default-remote subcommand Atharva Raykar
2021-09-07 11:59 ` [PATCH 12/13] submodule--helper: remove relative-path subcommand Atharva Raykar
2021-09-07 11:59 ` [PATCH 13/13] submodule--helper: remove run-update-procedure subcommand Atharva Raykar
2021-09-07 12:34 ` [PATCH 00/13] submodule: convert the rest of 'update' to C Ævar Arnfjörð Bjarmason
2021-09-07 12:53 ` Atharva Raykar
2021-09-16 10:32 ` [PATCH v2 0/8] " Atharva Raykar
2021-09-16 10:32 ` [PATCH v2 1/8] submodule--helper: split up ensure_core_worktree() Atharva Raykar
2021-09-16 10:32 ` [PATCH v2 2/8] submodule--helper: get remote names from any repository Atharva Raykar
2021-09-20 16:52 ` Junio C Hamano
2021-10-03 13:22 ` Atharva Raykar
2021-09-20 21:28 ` Junio C Hamano
2021-09-21 16:33 ` Jonathan Tan
2021-09-16 10:32 ` [PATCH v2 3/8] submodule--helper: rename helpers for update-clone Atharva Raykar
2021-09-16 10:32 ` [PATCH v2 4/8] submodule--helper: refactor get_submodule_displaypath() Atharva Raykar
2021-09-16 10:32 ` [PATCH v2 5/8] submodule: move core cmd_update() logic to C Atharva Raykar
2021-09-20 17:13 ` Junio C Hamano
2021-10-03 10:38 ` Atharva Raykar
2021-09-20 19:58 ` Junio C Hamano
2021-09-20 21:28 ` Junio C Hamano
2021-09-16 10:32 ` [PATCH v2 6/8] submodule--helper: remove update-clone subcommand Atharva Raykar
2021-09-16 10:32 ` [PATCH v2 7/8] submodule--helper: remove unused helpers Atharva Raykar
2021-09-20 17:19 ` Junio C Hamano
2021-09-16 10:32 ` [PATCH v2 8/8] submodule--helper: rename helper functions Atharva Raykar
2021-09-20 17:19 ` Junio C Hamano
2021-10-13 5:17 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Atharva Raykar
2021-10-13 5:17 ` [PATCH v3 1/9] submodule--helper: split up ensure_core_worktree() Atharva Raykar
2021-10-13 5:17 ` [PATCH v3 2/9] submodule--helper: get remote names from any repository Atharva Raykar
2021-10-13 5:17 ` [PATCH v3 3/9] submodule--helper: rename helpers for update-clone Atharva Raykar
2021-10-13 5:18 ` [PATCH v3 4/9] submodule--helper: refactor get_submodule_displaypath() Atharva Raykar
2021-10-13 5:18 ` [PATCH v3 5/9] submodule--helper: allow setting superprefix for init_submodule() Atharva Raykar
2021-10-13 5:18 ` [PATCH v3 6/9] submodule--helper: run update using child process struct Atharva Raykar
2021-10-13 5:18 ` [PATCH v3 7/9] submodule: move core cmd_update() logic to C Atharva Raykar
2021-10-13 5:18 ` [PATCH v3 8/9] submodule--helper: remove unused helpers Atharva Raykar
2021-10-13 5:18 ` [PATCH v3 9/9] submodule--helper: rename helper functions Atharva Raykar
2021-10-14 0:05 ` [PATCH v3 0/9] submodule: convert the rest of 'update' to C Junio C Hamano
2021-10-14 20:46 ` Emily Shaffer
2021-12-03 19:00 ` Junio C Hamano
2021-12-03 20:15 ` Ævar Arnfjörð Bjarmason
2021-12-04 10:38 ` Atharva Raykar
2022-01-27 16:22 ` [PATCH v4 0/7] " Ævar Arnfjörð Bjarmason
2022-01-27 16:22 ` [PATCH v4 1/7] submodule--helper: get remote names from any repository Ævar Arnfjörð Bjarmason
2022-01-27 18:45 ` Glen Choo
2022-01-27 16:22 ` [PATCH v4 2/7] submodule--helper: refactor get_submodule_displaypath() Ævar Arnfjörð Bjarmason
2022-01-27 16:22 ` [PATCH v4 3/7] submodule--helper: allow setting superprefix for init_submodule() Ævar Arnfjörð Bjarmason
2022-01-27 16:22 ` [PATCH v4 4/7] submodule--helper: run update using child process struct Ævar Arnfjörð Bjarmason
2022-01-27 16:22 ` [PATCH v4 5/7] builtin/submodule--helper.c: reformat designated initializers Ævar Arnfjörð Bjarmason
2022-01-27 16:22 ` [PATCH v4 6/7] builtin/submodule--helper.c: rename "suc" variable to "opt" Ævar Arnfjörð Bjarmason
2022-01-27 16:22 ` [PATCH v4 7/7] submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason
2022-01-27 21:55 ` Glen Choo
2022-01-28 12:56 ` [PATCH v5 0/9] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason
2022-01-28 12:56 ` [PATCH v5 1/9] submodule--helper: get remote names from any repository Ævar Arnfjörð Bjarmason
2022-01-28 12:56 ` [PATCH v5 2/9] submodule--helper: refactor get_submodule_displaypath() Ævar Arnfjörð Bjarmason
2022-01-28 12:56 ` [PATCH v5 3/9] submodule--helper: allow setting superprefix for init_submodule() Ævar Arnfjörð Bjarmason
2022-01-28 12:56 ` [PATCH v5 4/9] submodule--helper: run update using child process struct Ævar Arnfjörð Bjarmason
2022-01-28 12:56 ` [PATCH v5 5/9] builtin/submodule--helper.c: reformat designated initializers Ævar Arnfjörð Bjarmason
2022-01-28 12:56 ` [PATCH v5 6/9] builtin/submodule--helper.c: rename option variables to "opt" Ævar Arnfjörð Bjarmason
2022-01-28 12:56 ` [PATCH v5 7/9] submodule--helper: don't use bitfield indirection for parse_options() Ævar Arnfjörð Bjarmason
2022-01-28 12:56 ` [PATCH v5 8/9] submodule tests: test for init and update failure output Ævar Arnfjörð Bjarmason
2022-01-28 12:56 ` [PATCH v5 9/9] submodule: move core cmd_update() logic to C Ævar Arnfjörð Bjarmason
2022-02-03 0:18 ` Glen Choo
2022-02-03 2:26 ` Ævar Arnfjörð Bjarmason
2022-02-03 8:15 ` Ævar Arnfjörð Bjarmason
2022-02-03 17:35 ` Glen Choo
2022-02-08 8:39 ` [PATCH v6 00/16] submodule: convert the rest of 'update' " Glen Choo
2022-02-08 8:39 ` [PATCH v6 01/16] submodule--helper: get remote names from any repository Glen Choo
2022-02-08 8:39 ` [PATCH v6 02/16] submodule--helper: refactor get_submodule_displaypath() Glen Choo
2022-02-08 8:39 ` [PATCH v6 03/16] submodule--helper: allow setting superprefix for init_submodule() Glen Choo
2022-02-08 8:39 ` [PATCH v6 04/16] submodule--helper: run update using child process struct Glen Choo
2022-02-08 8:39 ` [PATCH v6 05/16] builtin/submodule--helper.c: reformat designated initializers Glen Choo
2022-02-08 8:39 ` [PATCH v6 06/16] builtin/submodule--helper.c: rename option variables to "opt" Glen Choo
2022-02-08 8:39 ` [PATCH v6 07/16] submodule--helper: don't use bitfield indirection for parse_options() Glen Choo
2022-02-08 8:39 ` [PATCH v6 08/16] submodule tests: test for init and update failure output Glen Choo
2022-02-08 8:39 ` [PATCH v6 09/16] submodule--helper: remove update-module-mode Glen Choo
2022-02-08 8:39 ` [PATCH v6 10/16] submodule--helper: reorganize code for sh to C conversion Glen Choo
2022-02-08 8:39 ` [PATCH v6 11/16] submodule--helper run-update-procedure: remove --suboid Glen Choo
2022-02-08 8:39 ` [PATCH v6 12/16] submodule--helper run-update-procedure: learn --remote Glen Choo
2022-02-08 8:39 ` [PATCH v6 13/16] submodule--helper: remove ensure-core-worktree Glen Choo
2022-02-08 8:39 ` [PATCH v6 14/16] submodule--helper update-clone: learn --init Glen Choo
2022-02-08 8:39 ` [PATCH v6 15/16] submodule--helper: move functions around Glen Choo
2022-02-08 8:39 ` [PATCH v6 16/16] submodule: move core cmd_update() logic to C Glen Choo
2022-02-10 9:28 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Glen Choo
2022-02-10 9:28 ` [PATCH v7 01/20] submodule--helper: get remote names from any repository Glen Choo
2022-02-10 9:28 ` [PATCH v7 02/20] submodule--helper: refactor get_submodule_displaypath() Glen Choo
2022-02-12 14:24 ` Ævar Arnfjörð Bjarmason
2022-02-10 9:28 ` [PATCH v7 03/20] submodule--helper: allow setting superprefix for init_submodule() Glen Choo
2022-02-12 14:30 ` Ævar Arnfjörð Bjarmason
2022-02-10 9:28 ` [PATCH v7 04/20] submodule--helper: run update using child process struct Glen Choo
2022-02-12 14:33 ` Ævar Arnfjörð Bjarmason
2022-02-10 9:28 ` [PATCH v7 05/20] builtin/submodule--helper.c: reformat designated initializers Glen Choo
2022-02-10 9:28 ` [PATCH v7 06/20] builtin/submodule--helper.c: rename option variables to "opt" Glen Choo
2022-02-10 9:28 ` [PATCH v7 07/20] submodule--helper: don't use bitfield indirection for parse_options() Glen Choo
2022-02-10 9:28 ` [PATCH v7 08/20] submodule tests: test for init and update failure output Glen Choo
2022-02-10 9:28 ` [PATCH v7 09/20] submodule--helper: remove update-module-mode Glen Choo
2022-02-12 14:35 ` Ævar Arnfjörð Bjarmason
2022-02-10 9:28 ` [PATCH v7 10/20] submodule--helper: reorganize code for sh to C conversion Glen Choo
2022-02-10 9:28 ` [PATCH v7 11/20] submodule--helper run-update-procedure: remove --suboid Glen Choo
2022-02-10 9:28 ` [PATCH v7 12/20] submodule--helper run-update-procedure: learn --remote Glen Choo
2022-02-12 14:38 ` Ævar Arnfjörð Bjarmason
2022-02-10 9:28 ` [PATCH v7 13/20] submodule--helper: remove ensure-core-worktree Glen Choo
2022-02-10 9:28 ` [PATCH v7 14/20] submodule--helper update-clone: learn --init Glen Choo
2022-02-10 9:28 ` [PATCH v7 15/20] submodule--helper: move functions around Glen Choo
2022-02-12 14:41 ` Ævar Arnfjörð Bjarmason
2022-02-10 9:28 ` [PATCH v7 16/20] submodule--helper: reduce logic in run_update_procedure() Glen Choo
2022-02-10 9:28 ` [PATCH v7 17/20] submodule: move core cmd_update() logic to C Glen Choo
2022-02-10 9:34 ` Glen Choo
2022-02-10 9:28 ` [PATCH v7 18/20] fixup! submodule--helper run-update-procedure: remove --suboid Glen Choo
2022-02-12 14:41 ` Ævar Arnfjörð Bjarmason
2022-02-10 9:28 ` [PATCH v7 19/20] fixup! submodule--helper run-update-procedure: learn --remote Glen Choo
2022-02-12 14:43 ` Ævar Arnfjörð Bjarmason
2022-02-10 9:28 ` [PATCH v7 20/20] fixup! submodule: move core cmd_update() logic to C Glen Choo
2022-02-12 14:45 ` [PATCH v7 00/20] submodule: convert the rest of 'update' " Ævar Arnfjörð Bjarmason
2022-02-17 5:44 ` Glen Choo
2022-02-17 9:17 ` Ævar Arnfjörð Bjarmason
2022-02-17 16:14 ` Glen Choo
2022-02-13 5:54 ` Junio C Hamano
2022-02-13 6:14 ` Junio C Hamano
2022-02-14 16:37 ` Glen Choo
2022-02-14 17:19 ` Ævar Arnfjörð Bjarmason
2022-02-15 9:34 ` Glen Choo
2022-02-14 17:34 ` Junio C Hamano
2022-02-15 9:31 ` Glen Choo
2022-02-15 9:47 ` Glen Choo
2021-10-14 21:50 ` [PATCH 00/13] " Glen Choo
2021-10-15 9:13 ` Atharva Raykar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210907115932.36068-7-raykar.ath@gmail.com \
--to=raykar.ath@gmail.com \
--cc=avarab@gmail.com \
--cc=christian.couder@gmail.com \
--cc=emilyshaffer@google.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jrnieder@gmail.com \
--cc=kaartic.sivaraam@gmail.com \
--cc=pc44800@gmail.com \
--cc=periperidip@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.