cdae54426b744e120bd8720c893363c35b625265
1#include "builtin.h"
2#include "repository.h"
3#include "cache.h"
4#include "config.h"
5#include "parse-options.h"
6#include "quote.h"
7#include "pathspec.h"
8#include "dir.h"
9#include "submodule.h"
10#include "submodule-config.h"
11#include "string-list.h"
12#include "run-command.h"
13#include "remote.h"
14#include "refs.h"
15#include "connect.h"
16
17static char *get_default_remote(void)
18{
19 char *dest = NULL, *ret;
20 unsigned char sha1[20];
21 struct strbuf sb = STRBUF_INIT;
22 const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
23
24 if (!refname)
25 die(_("No such ref: %s"), "HEAD");
26
27 /* detached HEAD */
28 if (!strcmp(refname, "HEAD"))
29 return xstrdup("origin");
30
31 if (!skip_prefix(refname, "refs/heads/", &refname))
32 die(_("Expecting a full ref name, got %s"), refname);
33
34 strbuf_addf(&sb, "branch.%s.remote", refname);
35 if (git_config_get_string(sb.buf, &dest))
36 ret = xstrdup("origin");
37 else
38 ret = dest;
39
40 strbuf_release(&sb);
41 return ret;
42}
43
44static int starts_with_dot_slash(const char *str)
45{
46 return str[0] == '.' && is_dir_sep(str[1]);
47}
48
49static int starts_with_dot_dot_slash(const char *str)
50{
51 return str[0] == '.' && str[1] == '.' && is_dir_sep(str[2]);
52}
53
54/*
55 * Returns 1 if it was the last chop before ':'.
56 */
57static int chop_last_dir(char **remoteurl, int is_relative)
58{
59 char *rfind = find_last_dir_sep(*remoteurl);
60 if (rfind) {
61 *rfind = '\0';
62 return 0;
63 }
64
65 rfind = strrchr(*remoteurl, ':');
66 if (rfind) {
67 *rfind = '\0';
68 return 1;
69 }
70
71 if (is_relative || !strcmp(".", *remoteurl))
72 die(_("cannot strip one component off url '%s'"),
73 *remoteurl);
74
75 free(*remoteurl);
76 *remoteurl = xstrdup(".");
77 return 0;
78}
79
80/*
81 * The `url` argument is the URL that navigates to the submodule origin
82 * repo. When relative, this URL is relative to the superproject origin
83 * URL repo. The `up_path` argument, if specified, is the relative
84 * path that navigates from the submodule working tree to the superproject
85 * working tree. Returns the origin URL of the submodule.
86 *
87 * Return either an absolute URL or filesystem path (if the superproject
88 * origin URL is an absolute URL or filesystem path, respectively) or a
89 * relative file system path (if the superproject origin URL is a relative
90 * file system path).
91 *
92 * When the output is a relative file system path, the path is either
93 * relative to the submodule working tree, if up_path is specified, or to
94 * the superproject working tree otherwise.
95 *
96 * NEEDSWORK: This works incorrectly on the domain and protocol part.
97 * remote_url url outcome expectation
98 * http://a.com/b ../c http://a.com/c as is
99 * http://a.com/b/ ../c http://a.com/c same as previous line, but
100 * ignore trailing slash in url
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 http:c error out
104 * http://a.com/b ../../../../../c .:c error out
105 * NEEDSWORK: Given how chop_last_dir() works, this function is broken
106 * when a local part has a colon in its path component, too.
107 */
108static char *relative_url(const char *remote_url,
109 const char *url,
110 const char *up_path)
111{
112 int is_relative = 0;
113 int colonsep = 0;
114 char *out;
115 char *remoteurl = xstrdup(remote_url);
116 struct strbuf sb = STRBUF_INIT;
117 size_t len = strlen(remoteurl);
118
119 if (is_dir_sep(remoteurl[len-1]))
120 remoteurl[len-1] = '\0';
121
122 if (!url_is_local_not_ssh(remoteurl) || is_absolute_path(remoteurl))
123 is_relative = 0;
124 else {
125 is_relative = 1;
126 /*
127 * Prepend a './' to ensure all relative
128 * remoteurls start with './' or '../'
129 */
130 if (!starts_with_dot_slash(remoteurl) &&
131 !starts_with_dot_dot_slash(remoteurl)) {
132 strbuf_reset(&sb);
133 strbuf_addf(&sb, "./%s", remoteurl);
134 free(remoteurl);
135 remoteurl = strbuf_detach(&sb, NULL);
136 }
137 }
138 /*
139 * When the url starts with '../', remove that and the
140 * last directory in remoteurl.
141 */
142 while (url) {
143 if (starts_with_dot_dot_slash(url)) {
144 url += 3;
145 colonsep |= chop_last_dir(&remoteurl, is_relative);
146 } else if (starts_with_dot_slash(url))
147 url += 2;
148 else
149 break;
150 }
151 strbuf_reset(&sb);
152 strbuf_addf(&sb, "%s%s%s", remoteurl, colonsep ? ":" : "/", url);
153 if (ends_with(url, "/"))
154 strbuf_setlen(&sb, sb.len - 1);
155 free(remoteurl);
156
157 if (starts_with_dot_slash(sb.buf))
158 out = xstrdup(sb.buf + 2);
159 else
160 out = xstrdup(sb.buf);
161 strbuf_reset(&sb);
162
163 if (!up_path || !is_relative)
164 return out;
165
166 strbuf_addf(&sb, "%s%s", up_path, out);
167 free(out);
168 return strbuf_detach(&sb, NULL);
169}
170
171static int resolve_relative_url(int argc, const char **argv, const char *prefix)
172{
173 char *remoteurl = NULL;
174 char *remote = get_default_remote();
175 const char *up_path = NULL;
176 char *res;
177 const char *url;
178 struct strbuf sb = STRBUF_INIT;
179
180 if (argc != 2 && argc != 3)
181 die("resolve-relative-url only accepts one or two arguments");
182
183 url = argv[1];
184 strbuf_addf(&sb, "remote.%s.url", remote);
185 free(remote);
186
187 if (git_config_get_string(sb.buf, &remoteurl))
188 /* the repository is its own authoritative upstream */
189 remoteurl = xgetcwd();
190
191 if (argc == 3)
192 up_path = argv[2];
193
194 res = relative_url(remoteurl, url, up_path);
195 puts(res);
196 free(res);
197 free(remoteurl);
198 return 0;
199}
200
201static int resolve_relative_url_test(int argc, const char **argv, const char *prefix)
202{
203 char *remoteurl, *res;
204 const char *up_path, *url;
205
206 if (argc != 4)
207 die("resolve-relative-url-test only accepts three arguments: <up_path> <remoteurl> <url>");
208
209 up_path = argv[1];
210 remoteurl = xstrdup(argv[2]);
211 url = argv[3];
212
213 if (!strcmp(up_path, "(null)"))
214 up_path = NULL;
215
216 res = relative_url(remoteurl, url, up_path);
217 puts(res);
218 free(res);
219 free(remoteurl);
220 return 0;
221}
222
223/* the result should be freed by the caller. */
224static char *get_submodule_displaypath(const char *path, const char *prefix)
225{
226 const char *super_prefix = get_super_prefix();
227
228 if (prefix && super_prefix) {
229 BUG("cannot have prefix '%s' and superprefix '%s'",
230 prefix, super_prefix);
231 } else if (prefix) {
232 struct strbuf sb = STRBUF_INIT;
233 char *displaypath = xstrdup(relative_path(path, prefix, &sb));
234 strbuf_release(&sb);
235 return displaypath;
236 } else if (super_prefix) {
237 return xstrfmt("%s%s", super_prefix, path);
238 } else {
239 return xstrdup(path);
240 }
241}
242
243struct module_list {
244 const struct cache_entry **entries;
245 int alloc, nr;
246};
247#define MODULE_LIST_INIT { NULL, 0, 0 }
248
249static int module_list_compute(int argc, const char **argv,
250 const char *prefix,
251 struct pathspec *pathspec,
252 struct module_list *list)
253{
254 int i, result = 0;
255 char *ps_matched = NULL;
256 parse_pathspec(pathspec, 0,
257 PATHSPEC_PREFER_FULL,
258 prefix, argv);
259
260 if (pathspec->nr)
261 ps_matched = xcalloc(pathspec->nr, 1);
262
263 if (read_cache() < 0)
264 die(_("index file corrupt"));
265
266 for (i = 0; i < active_nr; i++) {
267 const struct cache_entry *ce = active_cache[i];
268
269 if (!match_pathspec(pathspec, ce->name, ce_namelen(ce),
270 0, ps_matched, 1) ||
271 !S_ISGITLINK(ce->ce_mode))
272 continue;
273
274 ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
275 list->entries[list->nr++] = ce;
276 while (i + 1 < active_nr &&
277 !strcmp(ce->name, active_cache[i + 1]->name))
278 /*
279 * Skip entries with the same name in different stages
280 * to make sure an entry is returned only once.
281 */
282 i++;
283 }
284
285 if (ps_matched && report_path_error(ps_matched, pathspec, prefix))
286 result = -1;
287
288 free(ps_matched);
289
290 return result;
291}
292
293static void module_list_active(struct module_list *list)
294{
295 int i;
296 struct module_list active_modules = MODULE_LIST_INIT;
297
298 for (i = 0; i < list->nr; i++) {
299 const struct cache_entry *ce = list->entries[i];
300
301 if (!is_submodule_active(the_repository, ce->name))
302 continue;
303
304 ALLOC_GROW(active_modules.entries,
305 active_modules.nr + 1,
306 active_modules.alloc);
307 active_modules.entries[active_modules.nr++] = ce;
308 }
309
310 free(list->entries);
311 *list = active_modules;
312}
313
314static int module_list(int argc, const char **argv, const char *prefix)
315{
316 int i;
317 struct pathspec pathspec;
318 struct module_list list = MODULE_LIST_INIT;
319
320 struct option module_list_options[] = {
321 OPT_STRING(0, "prefix", &prefix,
322 N_("path"),
323 N_("alternative anchor for relative paths")),
324 OPT_END()
325 };
326
327 const char *const git_submodule_helper_usage[] = {
328 N_("git submodule--helper list [--prefix=<path>] [<path>...]"),
329 NULL
330 };
331
332 argc = parse_options(argc, argv, prefix, module_list_options,
333 git_submodule_helper_usage, 0);
334
335 if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
336 return 1;
337
338 for (i = 0; i < list.nr; i++) {
339 const struct cache_entry *ce = list.entries[i];
340
341 if (ce_stage(ce))
342 printf("%06o %s U\t", ce->ce_mode, sha1_to_hex(null_sha1));
343 else
344 printf("%06o %s %d\t", ce->ce_mode,
345 oid_to_hex(&ce->oid), ce_stage(ce));
346
347 fprintf(stdout, "%s\n", ce->name);
348 }
349 return 0;
350}
351
352static void init_submodule(const char *path, const char *prefix, int quiet)
353{
354 const struct submodule *sub;
355 struct strbuf sb = STRBUF_INIT;
356 char *upd = NULL, *url = NULL, *displaypath;
357
358 displaypath = get_submodule_displaypath(path, prefix);
359
360 sub = submodule_from_path(&null_oid, path);
361
362 if (!sub)
363 die(_("No url found for submodule path '%s' in .gitmodules"),
364 displaypath);
365
366 /*
367 * NEEDSWORK: In a multi-working-tree world, this needs to be
368 * set in the per-worktree config.
369 *
370 * Set active flag for the submodule being initialized
371 */
372 if (!is_submodule_active(the_repository, path)) {
373 strbuf_addf(&sb, "submodule.%s.active", sub->name);
374 git_config_set_gently(sb.buf, "true");
375 strbuf_reset(&sb);
376 }
377
378 /*
379 * Copy url setting when it is not set yet.
380 * To look up the url in .git/config, we must not fall back to
381 * .gitmodules, so look it up directly.
382 */
383 strbuf_addf(&sb, "submodule.%s.url", sub->name);
384 if (git_config_get_string(sb.buf, &url)) {
385 if (!sub->url)
386 die(_("No url found for submodule path '%s' in .gitmodules"),
387 displaypath);
388
389 url = xstrdup(sub->url);
390
391 /* Possibly a url relative to parent */
392 if (starts_with_dot_dot_slash(url) ||
393 starts_with_dot_slash(url)) {
394 char *remoteurl, *relurl;
395 char *remote = get_default_remote();
396 struct strbuf remotesb = STRBUF_INIT;
397 strbuf_addf(&remotesb, "remote.%s.url", remote);
398 free(remote);
399
400 if (git_config_get_string(remotesb.buf, &remoteurl)) {
401 warning(_("could not lookup configuration '%s'. Assuming this repository is its own authoritative upstream."), remotesb.buf);
402 remoteurl = xgetcwd();
403 }
404 relurl = relative_url(remoteurl, url, NULL);
405 strbuf_release(&remotesb);
406 free(remoteurl);
407 free(url);
408 url = relurl;
409 }
410
411 if (git_config_set_gently(sb.buf, url))
412 die(_("Failed to register url for submodule path '%s'"),
413 displaypath);
414 if (!quiet)
415 fprintf(stderr,
416 _("Submodule '%s' (%s) registered for path '%s'\n"),
417 sub->name, url, displaypath);
418 }
419 strbuf_reset(&sb);
420
421 /* Copy "update" setting when it is not set yet */
422 strbuf_addf(&sb, "submodule.%s.update", sub->name);
423 if (git_config_get_string(sb.buf, &upd) &&
424 sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
425 if (sub->update_strategy.type == SM_UPDATE_COMMAND) {
426 fprintf(stderr, _("warning: command update mode suggested for submodule '%s'\n"),
427 sub->name);
428 upd = xstrdup("none");
429 } else
430 upd = xstrdup(submodule_strategy_to_string(&sub->update_strategy));
431
432 if (git_config_set_gently(sb.buf, upd))
433 die(_("Failed to register update mode for submodule path '%s'"), displaypath);
434 }
435 strbuf_release(&sb);
436 free(displaypath);
437 free(url);
438 free(upd);
439}
440
441static int module_init(int argc, const char **argv, const char *prefix)
442{
443 struct pathspec pathspec;
444 struct module_list list = MODULE_LIST_INIT;
445 int quiet = 0;
446 int i;
447
448 struct option module_init_options[] = {
449 OPT__QUIET(&quiet, N_("Suppress output for initializing a submodule")),
450 OPT_END()
451 };
452
453 const char *const git_submodule_helper_usage[] = {
454 N_("git submodule--helper init [<path>]"),
455 NULL
456 };
457
458 argc = parse_options(argc, argv, prefix, module_init_options,
459 git_submodule_helper_usage, 0);
460
461 if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
462 return 1;
463
464 /*
465 * If there are no path args and submodule.active is set then,
466 * by default, only initialize 'active' modules.
467 */
468 if (!argc && git_config_get_value_multi("submodule.active"))
469 module_list_active(&list);
470
471 for (i = 0; i < list.nr; i++)
472 init_submodule(list.entries[i]->name, prefix, quiet);
473
474 return 0;
475}
476
477static int module_name(int argc, const char **argv, const char *prefix)
478{
479 const struct submodule *sub;
480
481 if (argc != 2)
482 usage(_("git submodule--helper name <path>"));
483
484 sub = submodule_from_path(&null_oid, argv[1]);
485
486 if (!sub)
487 die(_("no submodule mapping found in .gitmodules for path '%s'"),
488 argv[1]);
489
490 printf("%s\n", sub->name);
491
492 return 0;
493}
494
495static int clone_submodule(const char *path, const char *gitdir, const char *url,
496 const char *depth, struct string_list *reference,
497 int quiet, int progress)
498{
499 struct child_process cp = CHILD_PROCESS_INIT;
500
501 argv_array_push(&cp.args, "clone");
502 argv_array_push(&cp.args, "--no-checkout");
503 if (quiet)
504 argv_array_push(&cp.args, "--quiet");
505 if (progress)
506 argv_array_push(&cp.args, "--progress");
507 if (depth && *depth)
508 argv_array_pushl(&cp.args, "--depth", depth, NULL);
509 if (reference->nr) {
510 struct string_list_item *item;
511 for_each_string_list_item(item, reference)
512 argv_array_pushl(&cp.args, "--reference",
513 item->string, NULL);
514 }
515 if (gitdir && *gitdir)
516 argv_array_pushl(&cp.args, "--separate-git-dir", gitdir, NULL);
517
518 argv_array_push(&cp.args, url);
519 argv_array_push(&cp.args, path);
520
521 cp.git_cmd = 1;
522 prepare_submodule_repo_env(&cp.env_array);
523 cp.no_stdin = 1;
524
525 return run_command(&cp);
526}
527
528struct submodule_alternate_setup {
529 const char *submodule_name;
530 enum SUBMODULE_ALTERNATE_ERROR_MODE {
531 SUBMODULE_ALTERNATE_ERROR_DIE,
532 SUBMODULE_ALTERNATE_ERROR_INFO,
533 SUBMODULE_ALTERNATE_ERROR_IGNORE
534 } error_mode;
535 struct string_list *reference;
536};
537#define SUBMODULE_ALTERNATE_SETUP_INIT { NULL, \
538 SUBMODULE_ALTERNATE_ERROR_IGNORE, NULL }
539
540static int add_possible_reference_from_superproject(
541 struct alternate_object_database *alt, void *sas_cb)
542{
543 struct submodule_alternate_setup *sas = sas_cb;
544
545 /*
546 * If the alternate object store is another repository, try the
547 * standard layout with .git/(modules/<name>)+/objects
548 */
549 if (ends_with(alt->path, "/objects")) {
550 char *sm_alternate;
551 struct strbuf sb = STRBUF_INIT;
552 struct strbuf err = STRBUF_INIT;
553 strbuf_add(&sb, alt->path, strlen(alt->path) - strlen("objects"));
554
555 /*
556 * We need to end the new path with '/' to mark it as a dir,
557 * otherwise a submodule name containing '/' will be broken
558 * as the last part of a missing submodule reference would
559 * be taken as a file name.
560 */
561 strbuf_addf(&sb, "modules/%s/", sas->submodule_name);
562
563 sm_alternate = compute_alternate_path(sb.buf, &err);
564 if (sm_alternate) {
565 string_list_append(sas->reference, xstrdup(sb.buf));
566 free(sm_alternate);
567 } else {
568 switch (sas->error_mode) {
569 case SUBMODULE_ALTERNATE_ERROR_DIE:
570 die(_("submodule '%s' cannot add alternate: %s"),
571 sas->submodule_name, err.buf);
572 case SUBMODULE_ALTERNATE_ERROR_INFO:
573 fprintf(stderr, _("submodule '%s' cannot add alternate: %s"),
574 sas->submodule_name, err.buf);
575 case SUBMODULE_ALTERNATE_ERROR_IGNORE:
576 ; /* nothing */
577 }
578 }
579 strbuf_release(&sb);
580 }
581
582 return 0;
583}
584
585static void prepare_possible_alternates(const char *sm_name,
586 struct string_list *reference)
587{
588 char *sm_alternate = NULL, *error_strategy = NULL;
589 struct submodule_alternate_setup sas = SUBMODULE_ALTERNATE_SETUP_INIT;
590
591 git_config_get_string("submodule.alternateLocation", &sm_alternate);
592 if (!sm_alternate)
593 return;
594
595 git_config_get_string("submodule.alternateErrorStrategy", &error_strategy);
596
597 if (!error_strategy)
598 error_strategy = xstrdup("die");
599
600 sas.submodule_name = sm_name;
601 sas.reference = reference;
602 if (!strcmp(error_strategy, "die"))
603 sas.error_mode = SUBMODULE_ALTERNATE_ERROR_DIE;
604 else if (!strcmp(error_strategy, "info"))
605 sas.error_mode = SUBMODULE_ALTERNATE_ERROR_INFO;
606 else if (!strcmp(error_strategy, "ignore"))
607 sas.error_mode = SUBMODULE_ALTERNATE_ERROR_IGNORE;
608 else
609 die(_("Value '%s' for submodule.alternateErrorStrategy is not recognized"), error_strategy);
610
611 if (!strcmp(sm_alternate, "superproject"))
612 foreach_alt_odb(add_possible_reference_from_superproject, &sas);
613 else if (!strcmp(sm_alternate, "no"))
614 ; /* do nothing */
615 else
616 die(_("Value '%s' for submodule.alternateLocation is not recognized"), sm_alternate);
617
618 free(sm_alternate);
619 free(error_strategy);
620}
621
622static int module_clone(int argc, const char **argv, const char *prefix)
623{
624 const char *name = NULL, *url = NULL, *depth = NULL;
625 int quiet = 0;
626 int progress = 0;
627 char *p, *path = NULL, *sm_gitdir;
628 struct strbuf sb = STRBUF_INIT;
629 struct string_list reference = STRING_LIST_INIT_NODUP;
630 char *sm_alternate = NULL, *error_strategy = NULL;
631
632 struct option module_clone_options[] = {
633 OPT_STRING(0, "prefix", &prefix,
634 N_("path"),
635 N_("alternative anchor for relative paths")),
636 OPT_STRING(0, "path", &path,
637 N_("path"),
638 N_("where the new submodule will be cloned to")),
639 OPT_STRING(0, "name", &name,
640 N_("string"),
641 N_("name of the new submodule")),
642 OPT_STRING(0, "url", &url,
643 N_("string"),
644 N_("url where to clone the submodule from")),
645 OPT_STRING_LIST(0, "reference", &reference,
646 N_("repo"),
647 N_("reference repository")),
648 OPT_STRING(0, "depth", &depth,
649 N_("string"),
650 N_("depth for shallow clones")),
651 OPT__QUIET(&quiet, "Suppress output for cloning a submodule"),
652 OPT_BOOL(0, "progress", &progress,
653 N_("force cloning progress")),
654 OPT_END()
655 };
656
657 const char *const git_submodule_helper_usage[] = {
658 N_("git submodule--helper clone [--prefix=<path>] [--quiet] "
659 "[--reference <repository>] [--name <name>] [--depth <depth>] "
660 "--url <url> --path <path>"),
661 NULL
662 };
663
664 argc = parse_options(argc, argv, prefix, module_clone_options,
665 git_submodule_helper_usage, 0);
666
667 if (argc || !url || !path || !*path)
668 usage_with_options(git_submodule_helper_usage,
669 module_clone_options);
670
671 strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
672 sm_gitdir = absolute_pathdup(sb.buf);
673 strbuf_reset(&sb);
674
675 if (!is_absolute_path(path)) {
676 strbuf_addf(&sb, "%s/%s", get_git_work_tree(), path);
677 path = strbuf_detach(&sb, NULL);
678 } else
679 path = xstrdup(path);
680
681 if (!file_exists(sm_gitdir)) {
682 if (safe_create_leading_directories_const(sm_gitdir) < 0)
683 die(_("could not create directory '%s'"), sm_gitdir);
684
685 prepare_possible_alternates(name, &reference);
686
687 if (clone_submodule(path, sm_gitdir, url, depth, &reference,
688 quiet, progress))
689 die(_("clone of '%s' into submodule path '%s' failed"),
690 url, path);
691 } else {
692 if (safe_create_leading_directories_const(path) < 0)
693 die(_("could not create directory '%s'"), path);
694 strbuf_addf(&sb, "%s/index", sm_gitdir);
695 unlink_or_warn(sb.buf);
696 strbuf_reset(&sb);
697 }
698
699 /* Connect module worktree and git dir */
700 connect_work_tree_and_git_dir(path, sm_gitdir);
701
702 p = git_pathdup_submodule(path, "config");
703 if (!p)
704 die(_("could not get submodule directory for '%s'"), path);
705
706 /* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */
707 git_config_get_string("submodule.alternateLocation", &sm_alternate);
708 if (sm_alternate)
709 git_config_set_in_file(p, "submodule.alternateLocation",
710 sm_alternate);
711 git_config_get_string("submodule.alternateErrorStrategy", &error_strategy);
712 if (error_strategy)
713 git_config_set_in_file(p, "submodule.alternateErrorStrategy",
714 error_strategy);
715
716 free(sm_alternate);
717 free(error_strategy);
718
719 strbuf_release(&sb);
720 free(sm_gitdir);
721 free(path);
722 free(p);
723 return 0;
724}
725
726struct submodule_update_clone {
727 /* index into 'list', the list of submodules to look into for cloning */
728 int current;
729 struct module_list list;
730 unsigned warn_if_uninitialized : 1;
731
732 /* update parameter passed via commandline */
733 struct submodule_update_strategy update;
734
735 /* configuration parameters which are passed on to the children */
736 int progress;
737 int quiet;
738 int recommend_shallow;
739 struct string_list references;
740 const char *depth;
741 const char *recursive_prefix;
742 const char *prefix;
743
744 /* Machine-readable status lines to be consumed by git-submodule.sh */
745 struct string_list projectlines;
746
747 /* If we want to stop as fast as possible and return an error */
748 unsigned quickstop : 1;
749
750 /* failed clones to be retried again */
751 const struct cache_entry **failed_clones;
752 int failed_clones_nr, failed_clones_alloc;
753};
754#define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
755 SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, \
756 NULL, NULL, NULL, \
757 STRING_LIST_INIT_DUP, 0, NULL, 0, 0}
758
759
760static void next_submodule_warn_missing(struct submodule_update_clone *suc,
761 struct strbuf *out, const char *displaypath)
762{
763 /*
764 * Only mention uninitialized submodules when their
765 * paths have been specified.
766 */
767 if (suc->warn_if_uninitialized) {
768 strbuf_addf(out,
769 _("Submodule path '%s' not initialized"),
770 displaypath);
771 strbuf_addch(out, '\n');
772 strbuf_addstr(out,
773 _("Maybe you want to use 'update --init'?"));
774 strbuf_addch(out, '\n');
775 }
776}
777
778/**
779 * Determine whether 'ce' needs to be cloned. If so, prepare the 'child' to
780 * run the clone. Returns 1 if 'ce' needs to be cloned, 0 otherwise.
781 */
782static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
783 struct child_process *child,
784 struct submodule_update_clone *suc,
785 struct strbuf *out)
786{
787 const struct submodule *sub = NULL;
788 const char *url = NULL;
789 const char *update_string;
790 enum submodule_update_type update_type;
791 char *key;
792 struct strbuf displaypath_sb = STRBUF_INIT;
793 struct strbuf sb = STRBUF_INIT;
794 const char *displaypath = NULL;
795 int needs_cloning = 0;
796
797 if (ce_stage(ce)) {
798 if (suc->recursive_prefix)
799 strbuf_addf(&sb, "%s/%s", suc->recursive_prefix, ce->name);
800 else
801 strbuf_addstr(&sb, ce->name);
802 strbuf_addf(out, _("Skipping unmerged submodule %s"), sb.buf);
803 strbuf_addch(out, '\n');
804 goto cleanup;
805 }
806
807 sub = submodule_from_path(&null_oid, ce->name);
808
809 if (suc->recursive_prefix)
810 displaypath = relative_path(suc->recursive_prefix,
811 ce->name, &displaypath_sb);
812 else
813 displaypath = ce->name;
814
815 if (!sub) {
816 next_submodule_warn_missing(suc, out, displaypath);
817 goto cleanup;
818 }
819
820 key = xstrfmt("submodule.%s.update", sub->name);
821 if (!repo_config_get_string_const(the_repository, key, &update_string)) {
822 update_type = parse_submodule_update_type(update_string);
823 } else {
824 update_type = sub->update_strategy.type;
825 }
826 free(key);
827
828 if (suc->update.type == SM_UPDATE_NONE
829 || (suc->update.type == SM_UPDATE_UNSPECIFIED
830 && update_type == SM_UPDATE_NONE)) {
831 strbuf_addf(out, _("Skipping submodule '%s'"), displaypath);
832 strbuf_addch(out, '\n');
833 goto cleanup;
834 }
835
836 /* Check if the submodule has been initialized. */
837 if (!is_submodule_active(the_repository, ce->name)) {
838 next_submodule_warn_missing(suc, out, displaypath);
839 goto cleanup;
840 }
841
842 strbuf_reset(&sb);
843 strbuf_addf(&sb, "submodule.%s.url", sub->name);
844 if (repo_config_get_string_const(the_repository, sb.buf, &url))
845 url = sub->url;
846
847 strbuf_reset(&sb);
848 strbuf_addf(&sb, "%s/.git", ce->name);
849 needs_cloning = !file_exists(sb.buf);
850
851 strbuf_reset(&sb);
852 strbuf_addf(&sb, "%06o %s %d %d\t%s\n", ce->ce_mode,
853 oid_to_hex(&ce->oid), ce_stage(ce),
854 needs_cloning, ce->name);
855 string_list_append(&suc->projectlines, sb.buf);
856
857 if (!needs_cloning)
858 goto cleanup;
859
860 child->git_cmd = 1;
861 child->no_stdin = 1;
862 child->stdout_to_stderr = 1;
863 child->err = -1;
864 argv_array_push(&child->args, "submodule--helper");
865 argv_array_push(&child->args, "clone");
866 if (suc->progress)
867 argv_array_push(&child->args, "--progress");
868 if (suc->quiet)
869 argv_array_push(&child->args, "--quiet");
870 if (suc->prefix)
871 argv_array_pushl(&child->args, "--prefix", suc->prefix, NULL);
872 if (suc->recommend_shallow && sub->recommend_shallow == 1)
873 argv_array_push(&child->args, "--depth=1");
874 argv_array_pushl(&child->args, "--path", sub->path, NULL);
875 argv_array_pushl(&child->args, "--name", sub->name, NULL);
876 argv_array_pushl(&child->args, "--url", url, NULL);
877 if (suc->references.nr) {
878 struct string_list_item *item;
879 for_each_string_list_item(item, &suc->references)
880 argv_array_pushl(&child->args, "--reference", item->string, NULL);
881 }
882 if (suc->depth)
883 argv_array_push(&child->args, suc->depth);
884
885cleanup:
886 strbuf_reset(&displaypath_sb);
887 strbuf_reset(&sb);
888
889 return needs_cloning;
890}
891
892static int update_clone_get_next_task(struct child_process *child,
893 struct strbuf *err,
894 void *suc_cb,
895 void **idx_task_cb)
896{
897 struct submodule_update_clone *suc = suc_cb;
898 const struct cache_entry *ce;
899 int index;
900
901 for (; suc->current < suc->list.nr; suc->current++) {
902 ce = suc->list.entries[suc->current];
903 if (prepare_to_clone_next_submodule(ce, child, suc, err)) {
904 int *p = xmalloc(sizeof(*p));
905 *p = suc->current;
906 *idx_task_cb = p;
907 suc->current++;
908 return 1;
909 }
910 }
911
912 /*
913 * The loop above tried cloning each submodule once, now try the
914 * stragglers again, which we can imagine as an extension of the
915 * entry list.
916 */
917 index = suc->current - suc->list.nr;
918 if (index < suc->failed_clones_nr) {
919 int *p;
920 ce = suc->failed_clones[index];
921 if (!prepare_to_clone_next_submodule(ce, child, suc, err)) {
922 suc->current ++;
923 strbuf_addstr(err, "BUG: submodule considered for "
924 "cloning, doesn't need cloning "
925 "any more?\n");
926 return 0;
927 }
928 p = xmalloc(sizeof(*p));
929 *p = suc->current;
930 *idx_task_cb = p;
931 suc->current ++;
932 return 1;
933 }
934
935 return 0;
936}
937
938static int update_clone_start_failure(struct strbuf *err,
939 void *suc_cb,
940 void *idx_task_cb)
941{
942 struct submodule_update_clone *suc = suc_cb;
943 suc->quickstop = 1;
944 return 1;
945}
946
947static int update_clone_task_finished(int result,
948 struct strbuf *err,
949 void *suc_cb,
950 void *idx_task_cb)
951{
952 const struct cache_entry *ce;
953 struct submodule_update_clone *suc = suc_cb;
954
955 int *idxP = idx_task_cb;
956 int idx = *idxP;
957 free(idxP);
958
959 if (!result)
960 return 0;
961
962 if (idx < suc->list.nr) {
963 ce = suc->list.entries[idx];
964 strbuf_addf(err, _("Failed to clone '%s'. Retry scheduled"),
965 ce->name);
966 strbuf_addch(err, '\n');
967 ALLOC_GROW(suc->failed_clones,
968 suc->failed_clones_nr + 1,
969 suc->failed_clones_alloc);
970 suc->failed_clones[suc->failed_clones_nr++] = ce;
971 return 0;
972 } else {
973 idx -= suc->list.nr;
974 ce = suc->failed_clones[idx];
975 strbuf_addf(err, _("Failed to clone '%s' a second time, aborting"),
976 ce->name);
977 strbuf_addch(err, '\n');
978 suc->quickstop = 1;
979 return 1;
980 }
981
982 return 0;
983}
984
985static int gitmodules_update_clone_config(const char *var, const char *value,
986 void *cb)
987{
988 int *max_jobs = cb;
989 if (!strcmp(var, "submodule.fetchjobs"))
990 *max_jobs = parse_submodule_fetchjobs(var, value);
991 return 0;
992}
993
994static int update_clone(int argc, const char **argv, const char *prefix)
995{
996 const char *update = NULL;
997 int max_jobs = 1;
998 struct string_list_item *item;
999 struct pathspec pathspec;
1000 struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT;
1001
1002 struct option module_update_clone_options[] = {
1003 OPT_STRING(0, "prefix", &prefix,
1004 N_("path"),
1005 N_("path into the working tree")),
1006 OPT_STRING(0, "recursive-prefix", &suc.recursive_prefix,
1007 N_("path"),
1008 N_("path into the working tree, across nested "
1009 "submodule boundaries")),
1010 OPT_STRING(0, "update", &update,
1011 N_("string"),
1012 N_("rebase, merge, checkout or none")),
1013 OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"),
1014 N_("reference repository")),
1015 OPT_STRING(0, "depth", &suc.depth, "<depth>",
1016 N_("Create a shallow clone truncated to the "
1017 "specified number of revisions")),
1018 OPT_INTEGER('j', "jobs", &max_jobs,
1019 N_("parallel jobs")),
1020 OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow,
1021 N_("whether the initial clone should follow the shallow recommendation")),
1022 OPT__QUIET(&suc.quiet, N_("don't print cloning progress")),
1023 OPT_BOOL(0, "progress", &suc.progress,
1024 N_("force cloning progress")),
1025 OPT_END()
1026 };
1027
1028 const char *const git_submodule_helper_usage[] = {
1029 N_("git submodule--helper update_clone [--prefix=<path>] [<path>...]"),
1030 NULL
1031 };
1032 suc.prefix = prefix;
1033
1034 config_from_gitmodules(gitmodules_update_clone_config, &max_jobs);
1035 git_config(gitmodules_update_clone_config, &max_jobs);
1036
1037 argc = parse_options(argc, argv, prefix, module_update_clone_options,
1038 git_submodule_helper_usage, 0);
1039
1040 if (update)
1041 if (parse_submodule_update_strategy(update, &suc.update) < 0)
1042 die(_("bad value for update parameter"));
1043
1044 if (module_list_compute(argc, argv, prefix, &pathspec, &suc.list) < 0)
1045 return 1;
1046
1047 if (pathspec.nr)
1048 suc.warn_if_uninitialized = 1;
1049
1050 run_processes_parallel(max_jobs,
1051 update_clone_get_next_task,
1052 update_clone_start_failure,
1053 update_clone_task_finished,
1054 &suc);
1055
1056 /*
1057 * We saved the output and put it out all at once now.
1058 * That means:
1059 * - the listener does not have to interleave their (checkout)
1060 * work with our fetching. The writes involved in a
1061 * checkout involve more straightforward sequential I/O.
1062 * - the listener can avoid doing any work if fetching failed.
1063 */
1064 if (suc.quickstop)
1065 return 1;
1066
1067 for_each_string_list_item(item, &suc.projectlines)
1068 fprintf(stdout, "%s", item->string);
1069
1070 return 0;
1071}
1072
1073static int resolve_relative_path(int argc, const char **argv, const char *prefix)
1074{
1075 struct strbuf sb = STRBUF_INIT;
1076 if (argc != 3)
1077 die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc);
1078
1079 printf("%s", relative_path(argv[1], argv[2], &sb));
1080 strbuf_release(&sb);
1081 return 0;
1082}
1083
1084static const char *remote_submodule_branch(const char *path)
1085{
1086 const struct submodule *sub;
1087 const char *branch = NULL;
1088 char *key;
1089
1090 sub = submodule_from_path(&null_oid, path);
1091 if (!sub)
1092 return NULL;
1093
1094 key = xstrfmt("submodule.%s.branch", sub->name);
1095 if (repo_config_get_string_const(the_repository, key, &branch))
1096 branch = sub->branch;
1097 free(key);
1098
1099 if (!branch)
1100 return "master";
1101
1102 if (!strcmp(branch, ".")) {
1103 unsigned char sha1[20];
1104 const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
1105
1106 if (!refname)
1107 die(_("No such ref: %s"), "HEAD");
1108
1109 /* detached HEAD */
1110 if (!strcmp(refname, "HEAD"))
1111 die(_("Submodule (%s) branch configured to inherit "
1112 "branch from superproject, but the superproject "
1113 "is not on any branch"), sub->name);
1114
1115 if (!skip_prefix(refname, "refs/heads/", &refname))
1116 die(_("Expecting a full ref name, got %s"), refname);
1117 return refname;
1118 }
1119
1120 return branch;
1121}
1122
1123static int resolve_remote_submodule_branch(int argc, const char **argv,
1124 const char *prefix)
1125{
1126 const char *ret;
1127 struct strbuf sb = STRBUF_INIT;
1128 if (argc != 2)
1129 die("submodule--helper remote-branch takes exactly one arguments, got %d", argc);
1130
1131 ret = remote_submodule_branch(argv[1]);
1132 if (!ret)
1133 die("submodule %s doesn't exist", argv[1]);
1134
1135 printf("%s", ret);
1136 strbuf_release(&sb);
1137 return 0;
1138}
1139
1140static int push_check(int argc, const char **argv, const char *prefix)
1141{
1142 struct remote *remote;
1143 const char *superproject_head;
1144 char *head;
1145 int detached_head = 0;
1146 struct object_id head_oid;
1147
1148 if (argc < 3)
1149 die("submodule--helper push-check requires at least 2 arguments");
1150
1151 /*
1152 * superproject's resolved head ref.
1153 * if HEAD then the superproject is in a detached head state, otherwise
1154 * it will be the resolved head ref.
1155 */
1156 superproject_head = argv[1];
1157 argv++;
1158 argc--;
1159 /* Get the submodule's head ref and determine if it is detached */
1160 head = resolve_refdup("HEAD", 0, head_oid.hash, NULL);
1161 if (!head)
1162 die(_("Failed to resolve HEAD as a valid ref."));
1163 if (!strcmp(head, "HEAD"))
1164 detached_head = 1;
1165
1166 /*
1167 * The remote must be configured.
1168 * This is to avoid pushing to the exact same URL as the parent.
1169 */
1170 remote = pushremote_get(argv[1]);
1171 if (!remote || remote->origin == REMOTE_UNCONFIGURED)
1172 die("remote '%s' not configured", argv[1]);
1173
1174 /* Check the refspec */
1175 if (argc > 2) {
1176 int i, refspec_nr = argc - 2;
1177 struct ref *local_refs = get_local_heads();
1178 struct refspec *refspec = parse_push_refspec(refspec_nr,
1179 argv + 2);
1180
1181 for (i = 0; i < refspec_nr; i++) {
1182 struct refspec *rs = refspec + i;
1183
1184 if (rs->pattern || rs->matching)
1185 continue;
1186
1187 /* LHS must match a single ref */
1188 switch (count_refspec_match(rs->src, local_refs, NULL)) {
1189 case 1:
1190 break;
1191 case 0:
1192 /*
1193 * If LHS matches 'HEAD' then we need to ensure
1194 * that it matches the same named branch
1195 * checked out in the superproject.
1196 */
1197 if (!strcmp(rs->src, "HEAD")) {
1198 if (!detached_head &&
1199 !strcmp(head, superproject_head))
1200 break;
1201 die("HEAD does not match the named branch in the superproject");
1202 }
1203 default:
1204 die("src refspec '%s' must name a ref",
1205 rs->src);
1206 }
1207 }
1208 free_refspec(refspec_nr, refspec);
1209 }
1210 free(head);
1211
1212 return 0;
1213}
1214
1215static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
1216{
1217 int i;
1218 struct pathspec pathspec;
1219 struct module_list list = MODULE_LIST_INIT;
1220 unsigned flags = ABSORB_GITDIR_RECURSE_SUBMODULES;
1221
1222 struct option embed_gitdir_options[] = {
1223 OPT_STRING(0, "prefix", &prefix,
1224 N_("path"),
1225 N_("path into the working tree")),
1226 OPT_BIT(0, "--recursive", &flags, N_("recurse into submodules"),
1227 ABSORB_GITDIR_RECURSE_SUBMODULES),
1228 OPT_END()
1229 };
1230
1231 const char *const git_submodule_helper_usage[] = {
1232 N_("git submodule--helper embed-git-dir [<path>...]"),
1233 NULL
1234 };
1235
1236 argc = parse_options(argc, argv, prefix, embed_gitdir_options,
1237 git_submodule_helper_usage, 0);
1238
1239 if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
1240 return 1;
1241
1242 for (i = 0; i < list.nr; i++)
1243 absorb_git_dir_into_superproject(prefix,
1244 list.entries[i]->name, flags);
1245
1246 return 0;
1247}
1248
1249static int is_active(int argc, const char **argv, const char *prefix)
1250{
1251 if (argc != 2)
1252 die("submodule--helper is-active takes exactly 1 argument");
1253
1254 return !is_submodule_active(the_repository, argv[1]);
1255}
1256
1257#define SUPPORT_SUPER_PREFIX (1<<0)
1258
1259struct cmd_struct {
1260 const char *cmd;
1261 int (*fn)(int, const char **, const char *);
1262 unsigned option;
1263};
1264
1265static struct cmd_struct commands[] = {
1266 {"list", module_list, 0},
1267 {"name", module_name, 0},
1268 {"clone", module_clone, 0},
1269 {"update-clone", update_clone, 0},
1270 {"relative-path", resolve_relative_path, 0},
1271 {"resolve-relative-url", resolve_relative_url, 0},
1272 {"resolve-relative-url-test", resolve_relative_url_test, 0},
1273 {"init", module_init, SUPPORT_SUPER_PREFIX},
1274 {"remote-branch", resolve_remote_submodule_branch, 0},
1275 {"push-check", push_check, 0},
1276 {"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX},
1277 {"is-active", is_active, 0},
1278};
1279
1280int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
1281{
1282 int i;
1283 if (argc < 2 || !strcmp(argv[1], "-h"))
1284 usage("git submodule--helper <command>");
1285
1286 for (i = 0; i < ARRAY_SIZE(commands); i++) {
1287 if (!strcmp(argv[1], commands[i].cmd)) {
1288 if (get_super_prefix() &&
1289 !(commands[i].option & SUPPORT_SUPER_PREFIX))
1290 die(_("%s doesn't support --super-prefix"),
1291 commands[i].cmd);
1292 return commands[i].fn(argc - 1, argv + 1, prefix);
1293 }
1294 }
1295
1296 die(_("'%s' is not a valid submodule--helper "
1297 "subcommand"), argv[1]);
1298}