builtin / submodule--helper.con commit t0060: sidestep surprising path mangling results on Windows (77b63ac)
   1#include "builtin.h"
   2#include "cache.h"
   3#include "parse-options.h"
   4#include "quote.h"
   5#include "pathspec.h"
   6#include "dir.h"
   7#include "utf8.h"
   8#include "submodule.h"
   9#include "submodule-config.h"
  10#include "string-list.h"
  11#include "run-command.h"
  12#include "remote.h"
  13#include "refs.h"
  14#include "connect.h"
  15
  16static char *get_default_remote(void)
  17{
  18        char *dest = NULL, *ret;
  19        unsigned char sha1[20];
  20        struct strbuf sb = STRBUF_INIT;
  21        const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
  22
  23        if (!refname)
  24                die(_("No such ref: %s"), "HEAD");
  25
  26        /* detached HEAD */
  27        if (!strcmp(refname, "HEAD"))
  28                return xstrdup("origin");
  29
  30        if (!skip_prefix(refname, "refs/heads/", &refname))
  31                die(_("Expecting a full ref name, got %s"), refname);
  32
  33        strbuf_addf(&sb, "branch.%s.remote", refname);
  34        if (git_config_get_string(sb.buf, &dest))
  35                ret = xstrdup("origin");
  36        else
  37                ret = dest;
  38
  39        strbuf_release(&sb);
  40        return ret;
  41}
  42
  43static int starts_with_dot_slash(const char *str)
  44{
  45        return str[0] == '.' && is_dir_sep(str[1]);
  46}
  47
  48static int starts_with_dot_dot_slash(const char *str)
  49{
  50        return str[0] == '.' && str[1] == '.' && is_dir_sep(str[2]);
  51}
  52
  53/*
  54 * Returns 1 if it was the last chop before ':'.
  55 */
  56static int chop_last_dir(char **remoteurl, int is_relative)
  57{
  58        char *rfind = find_last_dir_sep(*remoteurl);
  59        if (rfind) {
  60                *rfind = '\0';
  61                return 0;
  62        }
  63
  64        rfind = strrchr(*remoteurl, ':');
  65        if (rfind) {
  66                *rfind = '\0';
  67                return 1;
  68        }
  69
  70        if (is_relative || !strcmp(".", *remoteurl))
  71                die(_("cannot strip one component off url '%s'"),
  72                        *remoteurl);
  73
  74        free(*remoteurl);
  75        *remoteurl = xstrdup(".");
  76        return 0;
  77}
  78
  79/*
  80 * The `url` argument is the URL that navigates to the submodule origin
  81 * repo. When relative, this URL is relative to the superproject origin
  82 * URL repo. The `up_path` argument, if specified, is the relative
  83 * path that navigates from the submodule working tree to the superproject
  84 * working tree. Returns the origin URL of the submodule.
  85 *
  86 * Return either an absolute URL or filesystem path (if the superproject
  87 * origin URL is an absolute URL or filesystem path, respectively) or a
  88 * relative file system path (if the superproject origin URL is a relative
  89 * file system path).
  90 *
  91 * When the output is a relative file system path, the path is either
  92 * relative to the submodule working tree, if up_path is specified, or to
  93 * the superproject working tree otherwise.
  94 *
  95 * NEEDSWORK: This works incorrectly on the domain and protocol part.
  96 * remote_url      url              outcome          expectation
  97 * http://a.com/b  ../c             http://a.com/c   as is
  98 * http://a.com/b/ ../c             http://a.com/c   same as previous line, but
  99 *                                                   ignore trailing slash in url
 100 * http://a.com/b  ../../c          http://c         error out
 101 * http://a.com/b  ../../../c       http:/c          error out
 102 * http://a.com/b  ../../../../c    http:c           error out
 103 * http://a.com/b  ../../../../../c    .:c           error out
 104 * NEEDSWORK: Given how chop_last_dir() works, this function is broken
 105 * when a local part has a colon in its path component, too.
 106 */
 107static char *relative_url(const char *remote_url,
 108                                const char *url,
 109                                const char *up_path)
 110{
 111        int is_relative = 0;
 112        int colonsep = 0;
 113        char *out;
 114        char *remoteurl = xstrdup(remote_url);
 115        struct strbuf sb = STRBUF_INIT;
 116        size_t len = strlen(remoteurl);
 117
 118        if (is_dir_sep(remoteurl[len-1]))
 119                remoteurl[len-1] = '\0';
 120
 121        if (!url_is_local_not_ssh(remoteurl) || is_absolute_path(remoteurl))
 122                is_relative = 0;
 123        else {
 124                is_relative = 1;
 125                /*
 126                 * Prepend a './' to ensure all relative
 127                 * remoteurls start with './' or '../'
 128                 */
 129                if (!starts_with_dot_slash(remoteurl) &&
 130                    !starts_with_dot_dot_slash(remoteurl)) {
 131                        strbuf_reset(&sb);
 132                        strbuf_addf(&sb, "./%s", remoteurl);
 133                        free(remoteurl);
 134                        remoteurl = strbuf_detach(&sb, NULL);
 135                }
 136        }
 137        /*
 138         * When the url starts with '../', remove that and the
 139         * last directory in remoteurl.
 140         */
 141        while (url) {
 142                if (starts_with_dot_dot_slash(url)) {
 143                        url += 3;
 144                        colonsep |= chop_last_dir(&remoteurl, is_relative);
 145                } else if (starts_with_dot_slash(url))
 146                        url += 2;
 147                else
 148                        break;
 149        }
 150        strbuf_reset(&sb);
 151        strbuf_addf(&sb, "%s%s%s", remoteurl, colonsep ? ":" : "/", url);
 152        if (ends_with(url, "/"))
 153                strbuf_setlen(&sb, sb.len - 1);
 154        free(remoteurl);
 155
 156        if (starts_with_dot_slash(sb.buf))
 157                out = xstrdup(sb.buf + 2);
 158        else
 159                out = xstrdup(sb.buf);
 160        strbuf_reset(&sb);
 161
 162        if (!up_path || !is_relative)
 163                return out;
 164
 165        strbuf_addf(&sb, "%s%s", up_path, out);
 166        free(out);
 167        return strbuf_detach(&sb, NULL);
 168}
 169
 170static int resolve_relative_url(int argc, const char **argv, const char *prefix)
 171{
 172        char *remoteurl = NULL;
 173        char *remote = get_default_remote();
 174        const char *up_path = NULL;
 175        char *res;
 176        const char *url;
 177        struct strbuf sb = STRBUF_INIT;
 178
 179        if (argc != 2 && argc != 3)
 180                die("resolve-relative-url only accepts one or two arguments");
 181
 182        url = argv[1];
 183        strbuf_addf(&sb, "remote.%s.url", remote);
 184        free(remote);
 185
 186        if (git_config_get_string(sb.buf, &remoteurl))
 187                /* the repository is its own authoritative upstream */
 188                remoteurl = xgetcwd();
 189
 190        if (argc == 3)
 191                up_path = argv[2];
 192
 193        res = relative_url(remoteurl, url, up_path);
 194        puts(res);
 195        free(res);
 196        free(remoteurl);
 197        return 0;
 198}
 199
 200static int resolve_relative_url_test(int argc, const char **argv, const char *prefix)
 201{
 202        char *remoteurl, *res;
 203        const char *up_path, *url;
 204
 205        if (argc != 4)
 206                die("resolve-relative-url-test only accepts three arguments: <up_path> <remoteurl> <url>");
 207
 208        up_path = argv[1];
 209        remoteurl = xstrdup(argv[2]);
 210        url = argv[3];
 211
 212        if (!strcmp(up_path, "(null)"))
 213                up_path = NULL;
 214
 215        res = relative_url(remoteurl, url, up_path);
 216        puts(res);
 217        free(res);
 218        free(remoteurl);
 219        return 0;
 220}
 221
 222struct module_list {
 223        const struct cache_entry **entries;
 224        int alloc, nr;
 225};
 226#define MODULE_LIST_INIT { NULL, 0, 0 }
 227
 228static int module_list_compute(int argc, const char **argv,
 229                               const char *prefix,
 230                               struct pathspec *pathspec,
 231                               struct module_list *list)
 232{
 233        int i, result = 0;
 234        char *ps_matched = NULL;
 235        parse_pathspec(pathspec, 0,
 236                       PATHSPEC_PREFER_FULL |
 237                       PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
 238                       prefix, argv);
 239
 240        if (pathspec->nr)
 241                ps_matched = xcalloc(pathspec->nr, 1);
 242
 243        if (read_cache() < 0)
 244                die(_("index file corrupt"));
 245
 246        for (i = 0; i < active_nr; i++) {
 247                const struct cache_entry *ce = active_cache[i];
 248
 249                if (!match_pathspec(pathspec, ce->name, ce_namelen(ce),
 250                                    0, ps_matched, 1) ||
 251                    !S_ISGITLINK(ce->ce_mode))
 252                        continue;
 253
 254                ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
 255                list->entries[list->nr++] = ce;
 256                while (i + 1 < active_nr &&
 257                       !strcmp(ce->name, active_cache[i + 1]->name))
 258                        /*
 259                         * Skip entries with the same name in different stages
 260                         * to make sure an entry is returned only once.
 261                         */
 262                        i++;
 263        }
 264
 265        if (ps_matched && report_path_error(ps_matched, pathspec, prefix))
 266                result = -1;
 267
 268        free(ps_matched);
 269
 270        return result;
 271}
 272
 273static int module_list(int argc, const char **argv, const char *prefix)
 274{
 275        int i;
 276        struct pathspec pathspec;
 277        struct module_list list = MODULE_LIST_INIT;
 278
 279        struct option module_list_options[] = {
 280                OPT_STRING(0, "prefix", &prefix,
 281                           N_("path"),
 282                           N_("alternative anchor for relative paths")),
 283                OPT_END()
 284        };
 285
 286        const char *const git_submodule_helper_usage[] = {
 287                N_("git submodule--helper list [--prefix=<path>] [<path>...]"),
 288                NULL
 289        };
 290
 291        argc = parse_options(argc, argv, prefix, module_list_options,
 292                             git_submodule_helper_usage, 0);
 293
 294        if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0) {
 295                printf("#unmatched\n");
 296                return 1;
 297        }
 298
 299        for (i = 0; i < list.nr; i++) {
 300                const struct cache_entry *ce = list.entries[i];
 301
 302                if (ce_stage(ce))
 303                        printf("%06o %s U\t", ce->ce_mode, sha1_to_hex(null_sha1));
 304                else
 305                        printf("%06o %s %d\t", ce->ce_mode, sha1_to_hex(ce->sha1), ce_stage(ce));
 306
 307                utf8_fprintf(stdout, "%s\n", ce->name);
 308        }
 309        return 0;
 310}
 311
 312static void init_submodule(const char *path, const char *prefix, int quiet)
 313{
 314        const struct submodule *sub;
 315        struct strbuf sb = STRBUF_INIT;
 316        char *upd = NULL, *url = NULL, *displaypath;
 317
 318        /* Only loads from .gitmodules, no overlay with .git/config */
 319        gitmodules_config();
 320
 321        if (prefix) {
 322                strbuf_addf(&sb, "%s%s", prefix, path);
 323                displaypath = strbuf_detach(&sb, NULL);
 324        } else
 325                displaypath = xstrdup(path);
 326
 327        sub = submodule_from_path(null_sha1, path);
 328
 329        if (!sub)
 330                die(_("No url found for submodule path '%s' in .gitmodules"),
 331                        displaypath);
 332
 333        /*
 334         * Copy url setting when it is not set yet.
 335         * To look up the url in .git/config, we must not fall back to
 336         * .gitmodules, so look it up directly.
 337         */
 338        strbuf_reset(&sb);
 339        strbuf_addf(&sb, "submodule.%s.url", sub->name);
 340        if (git_config_get_string(sb.buf, &url)) {
 341                url = xstrdup(sub->url);
 342
 343                if (!url)
 344                        die(_("No url found for submodule path '%s' in .gitmodules"),
 345                                displaypath);
 346
 347                /* Possibly a url relative to parent */
 348                if (starts_with_dot_dot_slash(url) ||
 349                    starts_with_dot_slash(url)) {
 350                        char *remoteurl, *relurl;
 351                        char *remote = get_default_remote();
 352                        struct strbuf remotesb = STRBUF_INIT;
 353                        strbuf_addf(&remotesb, "remote.%s.url", remote);
 354                        free(remote);
 355
 356                        if (git_config_get_string(remotesb.buf, &remoteurl))
 357                                /*
 358                                 * The repository is its own
 359                                 * authoritative upstream
 360                                 */
 361                                remoteurl = xgetcwd();
 362                        relurl = relative_url(remoteurl, url, NULL);
 363                        strbuf_release(&remotesb);
 364                        free(remoteurl);
 365                        free(url);
 366                        url = relurl;
 367                }
 368
 369                if (git_config_set_gently(sb.buf, url))
 370                        die(_("Failed to register url for submodule path '%s'"),
 371                            displaypath);
 372                if (!quiet)
 373                        fprintf(stderr,
 374                                _("Submodule '%s' (%s) registered for path '%s'\n"),
 375                                sub->name, url, displaypath);
 376        }
 377
 378        /* Copy "update" setting when it is not set yet */
 379        strbuf_reset(&sb);
 380        strbuf_addf(&sb, "submodule.%s.update", sub->name);
 381        if (git_config_get_string(sb.buf, &upd) &&
 382            sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
 383                if (sub->update_strategy.type == SM_UPDATE_COMMAND) {
 384                        fprintf(stderr, _("warning: command update mode suggested for submodule '%s'\n"),
 385                                sub->name);
 386                        upd = xstrdup("none");
 387                } else
 388                        upd = xstrdup(submodule_strategy_to_string(&sub->update_strategy));
 389
 390                if (git_config_set_gently(sb.buf, upd))
 391                        die(_("Failed to register update mode for submodule path '%s'"), displaypath);
 392        }
 393        strbuf_release(&sb);
 394        free(displaypath);
 395        free(url);
 396        free(upd);
 397}
 398
 399static int module_init(int argc, const char **argv, const char *prefix)
 400{
 401        struct pathspec pathspec;
 402        struct module_list list = MODULE_LIST_INIT;
 403        int quiet = 0;
 404        int i;
 405
 406        struct option module_init_options[] = {
 407                OPT_STRING(0, "prefix", &prefix,
 408                           N_("path"),
 409                           N_("alternative anchor for relative paths")),
 410                OPT__QUIET(&quiet, N_("Suppress output for initializing a submodule")),
 411                OPT_END()
 412        };
 413
 414        const char *const git_submodule_helper_usage[] = {
 415                N_("git submodule--helper init [<path>]"),
 416                NULL
 417        };
 418
 419        argc = parse_options(argc, argv, prefix, module_init_options,
 420                             git_submodule_helper_usage, 0);
 421
 422        if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
 423                return 1;
 424
 425        for (i = 0; i < list.nr; i++)
 426                init_submodule(list.entries[i]->name, prefix, quiet);
 427
 428        return 0;
 429}
 430
 431static int module_name(int argc, const char **argv, const char *prefix)
 432{
 433        const struct submodule *sub;
 434
 435        if (argc != 2)
 436                usage(_("git submodule--helper name <path>"));
 437
 438        gitmodules_config();
 439        sub = submodule_from_path(null_sha1, argv[1]);
 440
 441        if (!sub)
 442                die(_("no submodule mapping found in .gitmodules for path '%s'"),
 443                    argv[1]);
 444
 445        printf("%s\n", sub->name);
 446
 447        return 0;
 448}
 449static int clone_submodule(const char *path, const char *gitdir, const char *url,
 450                           const char *depth, const char *reference, int quiet)
 451{
 452        struct child_process cp;
 453        child_process_init(&cp);
 454
 455        argv_array_push(&cp.args, "clone");
 456        argv_array_push(&cp.args, "--no-checkout");
 457        if (quiet)
 458                argv_array_push(&cp.args, "--quiet");
 459        if (depth && *depth)
 460                argv_array_pushl(&cp.args, "--depth", depth, NULL);
 461        if (reference && *reference)
 462                argv_array_pushl(&cp.args, "--reference", reference, NULL);
 463        if (gitdir && *gitdir)
 464                argv_array_pushl(&cp.args, "--separate-git-dir", gitdir, NULL);
 465
 466        argv_array_push(&cp.args, url);
 467        argv_array_push(&cp.args, path);
 468
 469        cp.git_cmd = 1;
 470        cp.env = local_repo_env;
 471        cp.no_stdin = 1;
 472
 473        return run_command(&cp);
 474}
 475
 476static int module_clone(int argc, const char **argv, const char *prefix)
 477{
 478        const char *name = NULL, *url = NULL;
 479        const char *reference = NULL, *depth = NULL;
 480        int quiet = 0;
 481        FILE *submodule_dot_git;
 482        char *p, *path = NULL, *sm_gitdir;
 483        struct strbuf rel_path = STRBUF_INIT;
 484        struct strbuf sb = STRBUF_INIT;
 485
 486        struct option module_clone_options[] = {
 487                OPT_STRING(0, "prefix", &prefix,
 488                           N_("path"),
 489                           N_("alternative anchor for relative paths")),
 490                OPT_STRING(0, "path", &path,
 491                           N_("path"),
 492                           N_("where the new submodule will be cloned to")),
 493                OPT_STRING(0, "name", &name,
 494                           N_("string"),
 495                           N_("name of the new submodule")),
 496                OPT_STRING(0, "url", &url,
 497                           N_("string"),
 498                           N_("url where to clone the submodule from")),
 499                OPT_STRING(0, "reference", &reference,
 500                           N_("string"),
 501                           N_("reference repository")),
 502                OPT_STRING(0, "depth", &depth,
 503                           N_("string"),
 504                           N_("depth for shallow clones")),
 505                OPT__QUIET(&quiet, "Suppress output for cloning a submodule"),
 506                OPT_END()
 507        };
 508
 509        const char *const git_submodule_helper_usage[] = {
 510                N_("git submodule--helper clone [--prefix=<path>] [--quiet] "
 511                   "[--reference <repository>] [--name <name>] [--url <url>]"
 512                   "[--depth <depth>] [--] [<path>...]"),
 513                NULL
 514        };
 515
 516        argc = parse_options(argc, argv, prefix, module_clone_options,
 517                             git_submodule_helper_usage, 0);
 518
 519        if (!path || !*path)
 520                die(_("submodule--helper: unspecified or empty --path"));
 521
 522        strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
 523        sm_gitdir = xstrdup(absolute_path(sb.buf));
 524        strbuf_reset(&sb);
 525
 526        if (!is_absolute_path(path)) {
 527                strbuf_addf(&sb, "%s/%s", get_git_work_tree(), path);
 528                path = strbuf_detach(&sb, NULL);
 529        } else
 530                path = xstrdup(path);
 531
 532        if (!file_exists(sm_gitdir)) {
 533                if (safe_create_leading_directories_const(sm_gitdir) < 0)
 534                        die(_("could not create directory '%s'"), sm_gitdir);
 535                if (clone_submodule(path, sm_gitdir, url, depth, reference, quiet))
 536                        die(_("clone of '%s' into submodule path '%s' failed"),
 537                            url, path);
 538        } else {
 539                if (safe_create_leading_directories_const(path) < 0)
 540                        die(_("could not create directory '%s'"), path);
 541                strbuf_addf(&sb, "%s/index", sm_gitdir);
 542                unlink_or_warn(sb.buf);
 543                strbuf_reset(&sb);
 544        }
 545
 546        /* Write a .git file in the submodule to redirect to the superproject. */
 547        strbuf_addf(&sb, "%s/.git", path);
 548        if (safe_create_leading_directories_const(sb.buf) < 0)
 549                die(_("could not create leading directories of '%s'"), sb.buf);
 550        submodule_dot_git = fopen(sb.buf, "w");
 551        if (!submodule_dot_git)
 552                die_errno(_("cannot open file '%s'"), sb.buf);
 553
 554        fprintf_or_die(submodule_dot_git, "gitdir: %s\n",
 555                       relative_path(sm_gitdir, path, &rel_path));
 556        if (fclose(submodule_dot_git))
 557                die(_("could not close file %s"), sb.buf);
 558        strbuf_reset(&sb);
 559        strbuf_reset(&rel_path);
 560
 561        /* Redirect the worktree of the submodule in the superproject's config */
 562        p = git_pathdup_submodule(path, "config");
 563        if (!p)
 564                die(_("could not get submodule directory for '%s'"), path);
 565        git_config_set_in_file(p, "core.worktree",
 566                               relative_path(path, sm_gitdir, &rel_path));
 567        strbuf_release(&sb);
 568        strbuf_release(&rel_path);
 569        free(sm_gitdir);
 570        free(path);
 571        free(p);
 572        return 0;
 573}
 574
 575struct submodule_update_clone {
 576        /* index into 'list', the list of submodules to look into for cloning */
 577        int current;
 578        struct module_list list;
 579        unsigned warn_if_uninitialized : 1;
 580
 581        /* update parameter passed via commandline */
 582        struct submodule_update_strategy update;
 583
 584        /* configuration parameters which are passed on to the children */
 585        int quiet;
 586        const char *reference;
 587        const char *depth;
 588        const char *recursive_prefix;
 589        const char *prefix;
 590
 591        /* Machine-readable status lines to be consumed by git-submodule.sh */
 592        struct string_list projectlines;
 593
 594        /* If we want to stop as fast as possible and return an error */
 595        unsigned quickstop : 1;
 596};
 597#define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
 598        SUBMODULE_UPDATE_STRATEGY_INIT, 0, NULL, NULL, NULL, NULL, \
 599        STRING_LIST_INIT_DUP, 0}
 600
 601
 602static void next_submodule_warn_missing(struct submodule_update_clone *suc,
 603                struct strbuf *out, const char *displaypath)
 604{
 605        /*
 606         * Only mention uninitialized submodules when their
 607         * paths have been specified.
 608         */
 609        if (suc->warn_if_uninitialized) {
 610                strbuf_addf(out,
 611                        _("Submodule path '%s' not initialized"),
 612                        displaypath);
 613                strbuf_addch(out, '\n');
 614                strbuf_addstr(out,
 615                        _("Maybe you want to use 'update --init'?"));
 616                strbuf_addch(out, '\n');
 617        }
 618}
 619
 620/**
 621 * Determine whether 'ce' needs to be cloned. If so, prepare the 'child' to
 622 * run the clone. Returns 1 if 'ce' needs to be cloned, 0 otherwise.
 623 */
 624static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 625                                           struct child_process *child,
 626                                           struct submodule_update_clone *suc,
 627                                           struct strbuf *out)
 628{
 629        const struct submodule *sub = NULL;
 630        struct strbuf displaypath_sb = STRBUF_INIT;
 631        struct strbuf sb = STRBUF_INIT;
 632        const char *displaypath = NULL;
 633        char *url = NULL;
 634        int needs_cloning = 0;
 635
 636        if (ce_stage(ce)) {
 637                if (suc->recursive_prefix)
 638                        strbuf_addf(&sb, "%s/%s", suc->recursive_prefix, ce->name);
 639                else
 640                        strbuf_addf(&sb, "%s", ce->name);
 641                strbuf_addf(out, _("Skipping unmerged submodule %s"), sb.buf);
 642                strbuf_addch(out, '\n');
 643                goto cleanup;
 644        }
 645
 646        sub = submodule_from_path(null_sha1, ce->name);
 647
 648        if (suc->recursive_prefix)
 649                displaypath = relative_path(suc->recursive_prefix,
 650                                            ce->name, &displaypath_sb);
 651        else
 652                displaypath = ce->name;
 653
 654        if (!sub) {
 655                next_submodule_warn_missing(suc, out, displaypath);
 656                goto cleanup;
 657        }
 658
 659        if (suc->update.type == SM_UPDATE_NONE
 660            || (suc->update.type == SM_UPDATE_UNSPECIFIED
 661                && sub->update_strategy.type == SM_UPDATE_NONE)) {
 662                strbuf_addf(out, _("Skipping submodule '%s'"), displaypath);
 663                strbuf_addch(out, '\n');
 664                goto cleanup;
 665        }
 666
 667        /*
 668         * Looking up the url in .git/config.
 669         * We must not fall back to .gitmodules as we only want
 670         * to process configured submodules.
 671         */
 672        strbuf_reset(&sb);
 673        strbuf_addf(&sb, "submodule.%s.url", sub->name);
 674        git_config_get_string(sb.buf, &url);
 675        if (!url) {
 676                next_submodule_warn_missing(suc, out, displaypath);
 677                goto cleanup;
 678        }
 679
 680        strbuf_reset(&sb);
 681        strbuf_addf(&sb, "%s/.git", ce->name);
 682        needs_cloning = !file_exists(sb.buf);
 683
 684        strbuf_reset(&sb);
 685        strbuf_addf(&sb, "%06o %s %d %d\t%s\n", ce->ce_mode,
 686                        sha1_to_hex(ce->sha1), ce_stage(ce),
 687                        needs_cloning, ce->name);
 688        string_list_append(&suc->projectlines, sb.buf);
 689
 690        if (!needs_cloning)
 691                goto cleanup;
 692
 693        child->git_cmd = 1;
 694        child->no_stdin = 1;
 695        child->stdout_to_stderr = 1;
 696        child->err = -1;
 697        argv_array_push(&child->args, "submodule--helper");
 698        argv_array_push(&child->args, "clone");
 699        if (suc->quiet)
 700                argv_array_push(&child->args, "--quiet");
 701        if (suc->prefix)
 702                argv_array_pushl(&child->args, "--prefix", suc->prefix, NULL);
 703        argv_array_pushl(&child->args, "--path", sub->path, NULL);
 704        argv_array_pushl(&child->args, "--name", sub->name, NULL);
 705        argv_array_pushl(&child->args, "--url", url, NULL);
 706        if (suc->reference)
 707                argv_array_push(&child->args, suc->reference);
 708        if (suc->depth)
 709                argv_array_push(&child->args, suc->depth);
 710
 711cleanup:
 712        free(url);
 713        strbuf_reset(&displaypath_sb);
 714        strbuf_reset(&sb);
 715
 716        return needs_cloning;
 717}
 718
 719static int update_clone_get_next_task(struct child_process *child,
 720                                      struct strbuf *err,
 721                                      void *suc_cb,
 722                                      void **void_task_cb)
 723{
 724        struct submodule_update_clone *suc = suc_cb;
 725
 726        for (; suc->current < suc->list.nr; suc->current++) {
 727                const struct cache_entry *ce = suc->list.entries[suc->current];
 728                if (prepare_to_clone_next_submodule(ce, child, suc, err)) {
 729                        suc->current++;
 730                        return 1;
 731                }
 732        }
 733        return 0;
 734}
 735
 736static int update_clone_start_failure(struct strbuf *err,
 737                                      void *suc_cb,
 738                                      void *void_task_cb)
 739{
 740        struct submodule_update_clone *suc = suc_cb;
 741        suc->quickstop = 1;
 742        return 1;
 743}
 744
 745static int update_clone_task_finished(int result,
 746                                      struct strbuf *err,
 747                                      void *suc_cb,
 748                                      void *void_task_cb)
 749{
 750        struct submodule_update_clone *suc = suc_cb;
 751
 752        if (!result)
 753                return 0;
 754
 755        suc->quickstop = 1;
 756        return 1;
 757}
 758
 759static int update_clone(int argc, const char **argv, const char *prefix)
 760{
 761        const char *update = NULL;
 762        int max_jobs = -1;
 763        struct string_list_item *item;
 764        struct pathspec pathspec;
 765        struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT;
 766
 767        struct option module_update_clone_options[] = {
 768                OPT_STRING(0, "prefix", &prefix,
 769                           N_("path"),
 770                           N_("path into the working tree")),
 771                OPT_STRING(0, "recursive-prefix", &suc.recursive_prefix,
 772                           N_("path"),
 773                           N_("path into the working tree, across nested "
 774                              "submodule boundaries")),
 775                OPT_STRING(0, "update", &update,
 776                           N_("string"),
 777                           N_("rebase, merge, checkout or none")),
 778                OPT_STRING(0, "reference", &suc.reference, N_("repo"),
 779                           N_("reference repository")),
 780                OPT_STRING(0, "depth", &suc.depth, "<depth>",
 781                           N_("Create a shallow clone truncated to the "
 782                              "specified number of revisions")),
 783                OPT_INTEGER('j', "jobs", &max_jobs,
 784                            N_("parallel jobs")),
 785                OPT__QUIET(&suc.quiet, N_("don't print cloning progress")),
 786                OPT_END()
 787        };
 788
 789        const char *const git_submodule_helper_usage[] = {
 790                N_("git submodule--helper update_clone [--prefix=<path>] [<path>...]"),
 791                NULL
 792        };
 793        suc.prefix = prefix;
 794
 795        argc = parse_options(argc, argv, prefix, module_update_clone_options,
 796                             git_submodule_helper_usage, 0);
 797
 798        if (update)
 799                if (parse_submodule_update_strategy(update, &suc.update) < 0)
 800                        die(_("bad value for update parameter"));
 801
 802        if (module_list_compute(argc, argv, prefix, &pathspec, &suc.list) < 0)
 803                return 1;
 804
 805        if (pathspec.nr)
 806                suc.warn_if_uninitialized = 1;
 807
 808        /* Overlay the parsed .gitmodules file with .git/config */
 809        gitmodules_config();
 810        git_config(submodule_config, NULL);
 811
 812        if (max_jobs < 0)
 813                max_jobs = parallel_submodules();
 814
 815        run_processes_parallel(max_jobs,
 816                               update_clone_get_next_task,
 817                               update_clone_start_failure,
 818                               update_clone_task_finished,
 819                               &suc);
 820
 821        /*
 822         * We saved the output and put it out all at once now.
 823         * That means:
 824         * - the listener does not have to interleave their (checkout)
 825         *   work with our fetching.  The writes involved in a
 826         *   checkout involve more straightforward sequential I/O.
 827         * - the listener can avoid doing any work if fetching failed.
 828         */
 829        if (suc.quickstop)
 830                return 1;
 831
 832        for_each_string_list_item(item, &suc.projectlines)
 833                utf8_fprintf(stdout, "%s", item->string);
 834
 835        return 0;
 836}
 837
 838struct cmd_struct {
 839        const char *cmd;
 840        int (*fn)(int, const char **, const char *);
 841};
 842
 843static struct cmd_struct commands[] = {
 844        {"list", module_list},
 845        {"name", module_name},
 846        {"clone", module_clone},
 847        {"update-clone", update_clone},
 848        {"resolve-relative-url", resolve_relative_url},
 849        {"resolve-relative-url-test", resolve_relative_url_test},
 850        {"init", module_init}
 851};
 852
 853int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
 854{
 855        int i;
 856        if (argc < 2)
 857                die(_("submodule--helper subcommand must be "
 858                      "called with a subcommand"));
 859
 860        for (i = 0; i < ARRAY_SIZE(commands); i++)
 861                if (!strcmp(argv[1], commands[i].cmd))
 862                        return commands[i].fn(argc - 1, argv + 1, prefix);
 863
 864        die(_("'%s' is not a valid submodule--helper "
 865              "subcommand"), argv[1]);
 866}