From: Atharva Raykar <raykar.ath@gmail.com>
To: raykar.ath@gmail.com
Cc: avarab@gmail.com, christian.couder@gmail.com,
emilyshaffer@google.com, git@vger.kernel.org, gitster@pobox.com,
jrnieder@gmail.com, kaartic.sivaraam@gmail.com,
pc44800@gmail.com, periperidip@gmail.com
Subject: [PATCH v3 7/9] submodule: move core cmd_update() logic to C
Date: Wed, 13 Oct 2021 10:48:03 +0530 [thread overview]
Message-ID: <20211013051805.45662-8-raykar.ath@gmail.com> (raw)
In-Reply-To: <20211013051805.45662-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 in the same process.
While we are at it, we also remove the fetch_in_submodule() shell
function since it is no longer used anywhere.
[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 | 462 +++++++++++++++++++++++++++++++-----
git-submodule.sh | 145 +----------
2 files changed, 410 insertions(+), 197 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 640b3bd220..3049628f88 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2010,7 +2010,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;
@@ -2033,19 +2032,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)
@@ -2340,13 +2383,21 @@ 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 child_process cp = CHILD_PROCESS_INIT;
char *oid = oid_to_hex(&ud->oid);
+ struct strbuf out = STRBUF_INIT;
int must_die_on_failure = 0;
+ 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;
+
+ switch (strategy.type) {
case SM_UPDATE_CHECKOUT:
cp.git_cmd = 1;
strvec_pushl(&cp.args, "checkout", "-q", NULL);
@@ -2369,80 +2420,75 @@ static int run_update_command(struct update_data *ud, int subforce)
break;
case SM_UPDATE_COMMAND:
cp.use_shell = 1;
- strvec_push(&cp.args, ud->update_strategy.command);
+ 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(&cp.args, oid);
cp.dir = xstrdup(ud->sm_path);
prepare_submodule_repo_env(&cp.env_array);
- if (run_command(&cp)) {
- 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));
+ 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;
@@ -2469,7 +2515,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)
@@ -2574,6 +2620,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")),
@@ -2631,7 +2678,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;
}
@@ -3002,6 +3049,291 @@ 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) {
+ string_list_clear(&update_data->references, 0);
+ 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;
+ }
+
+ string_list_clear(&update_data->references, 0);
+ 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;
@@ -3360,6 +3692,7 @@ static int module_add(int argc, const char **argv, const char *prefix)
return 0;
}
+
#define SUPPORT_SUPER_PREFIX (1<<0)
struct cmd_struct {
@@ -3373,6 +3706,7 @@ static struct cmd_struct commands[] = {
{"name", module_name, 0},
{"clone", module_clone, 0},
{"add", module_add, SUPPORT_SUPER_PREFIX},
+ {"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 652861aa66..bcd8b92aab 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -246,20 +246,6 @@ cmd_deinit()
git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@"
}
-# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>]
-# Because arguments are positional, use an empty string to omit <depth>
-# but include <sha1>.
-fetch_in_submodule () (
- sanitize_submodule_env &&
- cd "$1" &&
- if test $# -eq 3
- then
- echo "$3" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+"$2"}
- else
- git fetch ${GIT_QUIET:+--quiet} ${2:+"$2"}
- fi
-)
-
#
# Update each submodule path to correct revision, using clone and checkout as needed
#
@@ -361,133 +347,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-10-13 5:19 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 ` [PATCH 06/13] submodule: move core cmd_update() logic to C Atharva Raykar
2021-09-07 12:40 ` Æ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 ` Atharva Raykar [this message]
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
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211013051805.45662-8-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.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).