clone: use a real progress meter for connectivity check
[gitweb.git] / builtin / submodule--helper.c
index 825a421fc928e108fd9b2972c89383533bc0d978..b22352b6e1e4c40d1a6e182f5c12abf6351f71fb 100644 (file)
@@ -287,10 +287,8 @@ static int module_list(int argc, const char **argv, const char *prefix)
        argc = parse_options(argc, argv, prefix, module_list_options,
                             git_submodule_helper_usage, 0);
 
-       if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0) {
-               printf("#unmatched\n");
+       if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
                return 1;
-       }
 
        for (i = 0; i < list.nr; i++) {
                const struct cache_entry *ce = list.entries[i];
@@ -443,54 +441,6 @@ static int module_name(int argc, const char **argv, const char *prefix)
        return 0;
 }
 
-/*
- * Rules to sanitize configuration variables that are Ok to be passed into
- * submodule operations from the parent project using "-c". Should only
- * include keys which are both (a) safe and (b) necessary for proper
- * operation.
- */
-static int submodule_config_ok(const char *var)
-{
-       if (starts_with(var, "credential."))
-               return 1;
-       return 0;
-}
-
-static int sanitize_submodule_config(const char *var, const char *value, void *data)
-{
-       struct strbuf *out = data;
-
-       if (submodule_config_ok(var)) {
-               if (out->len)
-                       strbuf_addch(out, ' ');
-
-               if (value)
-                       sq_quotef(out, "%s=%s", var, value);
-               else
-                       sq_quote_buf(out, var);
-       }
-
-       return 0;
-}
-
-static void prepare_submodule_repo_env(struct argv_array *out)
-{
-       const char * const *var;
-
-       for (var = local_repo_env; *var; var++) {
-               if (!strcmp(*var, CONFIG_DATA_ENVIRONMENT)) {
-                       struct strbuf sanitized_config = STRBUF_INIT;
-                       git_config_from_parameters(sanitize_submodule_config,
-                                                  &sanitized_config);
-                       argv_array_pushf(out, "%s=%s", *var, sanitized_config.buf);
-                       strbuf_release(&sanitized_config);
-               } else {
-                       argv_array_push(out, *var);
-               }
-       }
-
-}
-
 static int clone_submodule(const char *path, const char *gitdir, const char *url,
                           const char *depth, const char *reference, int quiet)
 {
@@ -618,22 +568,6 @@ static int module_clone(int argc, const char **argv, const char *prefix)
        return 0;
 }
 
-static int module_sanitize_config(int argc, const char **argv, const char *prefix)
-{
-       struct strbuf sanitized_config = STRBUF_INIT;
-
-       if (argc > 1)
-               usage(_("git submodule--helper sanitize-config"));
-
-       git_config_from_parameters(sanitize_submodule_config, &sanitized_config);
-       if (sanitized_config.len)
-               printf("%s\n", sanitized_config.buf);
-
-       strbuf_release(&sanitized_config);
-
-       return 0;
-}
-
 struct submodule_update_clone {
        /* index into 'list', the list of submodules to look into for cloning */
        int current;
@@ -645,6 +579,7 @@ struct submodule_update_clone {
 
        /* configuration parameters which are passed on to the children */
        int quiet;
+       int recommend_shallow;
        const char *reference;
        const char *depth;
        const char *recursive_prefix;
@@ -655,10 +590,14 @@ struct submodule_update_clone {
 
        /* If we want to stop as fast as possible and return an error */
        unsigned quickstop : 1;
+
+       /* failed clones to be retried again */
+       const struct cache_entry **failed_clones;
+       int failed_clones_nr, failed_clones_alloc;
 };
 #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
-       SUBMODULE_UPDATE_STRATEGY_INIT, 0, NULL, NULL, NULL, NULL, \
-       STRING_LIST_INIT_DUP, 0}
+       SUBMODULE_UPDATE_STRATEGY_INIT, 0, -1, NULL, NULL, NULL, NULL, \
+       STRING_LIST_INIT_DUP, 0, NULL, 0, 0}
 
 
 static void next_submodule_warn_missing(struct submodule_update_clone *suc,
@@ -762,6 +701,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
                argv_array_push(&child->args, "--quiet");
        if (suc->prefix)
                argv_array_pushl(&child->args, "--prefix", suc->prefix, NULL);
+       if (suc->recommend_shallow && sub->recommend_shallow == 1)
+               argv_array_push(&child->args, "--depth=1");
        argv_array_pushl(&child->args, "--path", sub->path, NULL);
        argv_array_pushl(&child->args, "--name", sub->name, NULL);
        argv_array_pushl(&child->args, "--url", url, NULL);
@@ -781,23 +722,47 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 static int update_clone_get_next_task(struct child_process *child,
                                      struct strbuf *err,
                                      void *suc_cb,
-                                     void **void_task_cb)
+                                     void **idx_task_cb)
 {
        struct submodule_update_clone *suc = suc_cb;
+       const struct cache_entry *ce;
+       int index;
 
        for (; suc->current < suc->list.nr; suc->current++) {
-               const struct cache_entry *ce = suc->list.entries[suc->current];
+               ce = suc->list.entries[suc->current];
                if (prepare_to_clone_next_submodule(ce, child, suc, err)) {
+                       int *p = xmalloc(sizeof(*p));
+                       *p = suc->current;
+                       *idx_task_cb = p;
                        suc->current++;
                        return 1;
                }
        }
+
+       /*
+        * The loop above tried cloning each submodule once, now try the
+        * stragglers again, which we can imagine as an extension of the
+        * entry list.
+        */
+       index = suc->current - suc->list.nr;
+       if (index < suc->failed_clones_nr) {
+               int *p;
+               ce = suc->failed_clones[index];
+               if (!prepare_to_clone_next_submodule(ce, child, suc, err))
+                       die("BUG: ce was a submodule before?");
+               p = xmalloc(sizeof(*p));
+               *p = suc->current;
+               *idx_task_cb = p;
+               suc->current ++;
+               return 1;
+       }
+
        return 0;
 }
 
 static int update_clone_start_failure(struct strbuf *err,
                                      void *suc_cb,
-                                     void *void_task_cb)
+                                     void *idx_task_cb)
 {
        struct submodule_update_clone *suc = suc_cb;
        suc->quickstop = 1;
@@ -807,15 +772,39 @@ static int update_clone_start_failure(struct strbuf *err,
 static int update_clone_task_finished(int result,
                                      struct strbuf *err,
                                      void *suc_cb,
-                                     void *void_task_cb)
+                                     void *idx_task_cb)
 {
+       const struct cache_entry *ce;
        struct submodule_update_clone *suc = suc_cb;
 
+       int *idxP = *(int**)idx_task_cb;
+       int idx = *idxP;
+       free(idxP);
+
        if (!result)
                return 0;
 
-       suc->quickstop = 1;
-       return 1;
+       if (idx < suc->list.nr) {
+               ce  = suc->list.entries[idx];
+               strbuf_addf(err, _("Failed to clone '%s'. Retry scheduled"),
+                           ce->name);
+               strbuf_addch(err, '\n');
+               ALLOC_GROW(suc->failed_clones,
+                          suc->failed_clones_nr + 1,
+                          suc->failed_clones_alloc);
+               suc->failed_clones[suc->failed_clones_nr++] = ce;
+               return 0;
+       } else {
+               idx = suc->current - suc->list.nr;
+               ce  = suc->failed_clones[idx];
+               strbuf_addf(err, _("Failed to clone '%s' a second time, aborting"),
+                           ce->name);
+               strbuf_addch(err, '\n');
+               suc->quickstop = 1;
+               return 1;
+       }
+
+       return 0;
 }
 
 static int update_clone(int argc, const char **argv, const char *prefix)
@@ -844,6 +833,8 @@ static int update_clone(int argc, const char **argv, const char *prefix)
                              "specified number of revisions")),
                OPT_INTEGER('j', "jobs", &max_jobs,
                            N_("parallel jobs")),
+               OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow,
+                           N_("whether the initial clone should follow the shallow recommendation")),
                OPT__QUIET(&suc.quiet, N_("don't print cloning progress")),
                OPT_END()
        };
@@ -897,6 +888,17 @@ static int update_clone(int argc, const char **argv, const char *prefix)
        return 0;
 }
 
+static int resolve_relative_path(int argc, const char **argv, const char *prefix)
+{
+       struct strbuf sb = STRBUF_INIT;
+       if (argc != 3)
+               die("submodule--helper relative_path takes exactly 2 arguments, got %d", argc);
+
+       printf("%s", relative_path(argv[1], argv[2], &sb));
+       strbuf_release(&sb);
+       return 0;
+}
+
 struct cmd_struct {
        const char *cmd;
        int (*fn)(int, const char **, const char *);
@@ -906,8 +908,8 @@ static struct cmd_struct commands[] = {
        {"list", module_list},
        {"name", module_name},
        {"clone", module_clone},
-       {"sanitize-config", module_sanitize_config},
        {"update-clone", update_clone},
+       {"relative-path", resolve_relative_path},
        {"resolve-relative-url", resolve_relative_url},
        {"resolve-relative-url-test", resolve_relative_url_test},
        {"init", module_init}