Hi Emily, On Thu, 16 Jan 2020, Emily Shaffer wrote: > In cases when a submodule fetch fails when there are many submodules, the error > from the lone failing submodule fetch is buried under activity on the other > submodules if more than one fetch fell back on fetch-by-oid. Call out a failure > late so the user is aware that something went wrong, and where. > > Because fetch_finish() is only called synchronously by > run_processes_parallel, mutexing is not required around > submodules_with_errors. > > Signed-off-by: Emily Shaffer <emilyshaffer@xxxxxxxxxx> > --- > Since v2, removed mutexing as run_processes_parallel() creates > subprocesses, not threads, and is in fact synchronous. Also added > translation marker for the error message. Excellent. For Git for Windows' ever-green branch based on `pu`, I had to introduce this: -- snip -- Subject: [PATCH] fixup??? fetch: emphasize failure during submodule fetch This would be the first user of `PTHREAD_MUTEX_INITIALIZER`, but as we have a hard time to emulate this with critical sections in Windows, let's not do that. Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx> --- submodule.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/submodule.c b/submodule.c index a65db54cece..ec54f4db2cd 100644 --- a/submodule.c +++ b/submodule.c @@ -1286,7 +1286,7 @@ struct submodule_parallel_fetch { }; #define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, \ STRING_LIST_INIT_DUP, \ - NULL, 0, 0, STRBUF_INIT, PTHREAD_MUTEX_INITIALIZER} + NULL, 0, 0, STRBUF_INIT} static int get_fetch_recurse_config(const struct submodule *submodule, struct submodule_parallel_fetch *spf) @@ -1614,6 +1614,7 @@ int fetch_populated_submodules(struct repository *r, spf.default_option = default_option; spf.quiet = quiet; spf.prefix = prefix; + pthread_mutex_init(&spf.submodule_errors_mutex, NULL); if (!r->worktree) goto out; -- snap -- I look forward to v3 hitting `pu` and making this change obsolete. Thanks, Dscho > > - Emily > > submodule.c | 19 +++++++++++++++---- > 1 file changed, 15 insertions(+), 4 deletions(-) > > diff --git a/submodule.c b/submodule.c > index 9da7181321..ee74acee27 100644 > --- a/submodule.c > +++ b/submodule.c > @@ -1280,10 +1280,12 @@ struct submodule_parallel_fetch { > /* Pending fetches by OIDs */ > struct fetch_task **oid_fetch_tasks; > int oid_fetch_tasks_nr, oid_fetch_tasks_alloc; > + > + struct strbuf submodules_with_errors; > }; > #define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, \ > STRING_LIST_INIT_DUP, \ > - NULL, 0, 0} > + NULL, 0, 0, STRBUF_INIT} > > static int get_fetch_recurse_config(const struct submodule *submodule, > struct submodule_parallel_fetch *spf) > @@ -1547,7 +1549,10 @@ static int fetch_finish(int retvalue, struct strbuf *err, > struct string_list_item *it; > struct oid_array *commits; > > - if (retvalue) > + if (!task || !task->sub) > + BUG("callback cookie bogus"); > + > + if (retvalue) { > /* > * NEEDSWORK: This indicates that the overall fetch > * failed, even though there may be a subsequent fetch > @@ -1557,8 +1562,9 @@ static int fetch_finish(int retvalue, struct strbuf *err, > */ > spf->result = 1; > > - if (!task || !task->sub) > - BUG("callback cookie bogus"); > + strbuf_addf(&spf->submodules_with_errors, "\t%s\n", > + task->sub->name); > + } > > /* Is this the second time we process this submodule? */ > if (task->commits) > @@ -1627,6 +1633,11 @@ int fetch_populated_submodules(struct repository *r, > &spf, > "submodule", "parallel/fetch"); > > + if (spf.submodules_with_errors.len > 0) > + fprintf(stderr, _("Errors during submodule fetch:\n%s"), > + spf.submodules_with_errors.buf); > + > + > argv_array_clear(&spf.args); > out: > free_submodules_oids(&spf.changed_submodule_names); > -- > 2.25.0.rc1.283.g88dfdc4193-goog > >