]> git.ipfire.org Git - thirdparty/git.git/blob - builtin/submodule--helper.c
Merge branch 'rs/dup-array'
[thirdparty/git.git] / builtin / submodule--helper.c
1 #define USE_THE_INDEX_VARIABLE
2 #include "builtin.h"
3 #include "repository.h"
4 #include "cache.h"
5 #include "config.h"
6 #include "parse-options.h"
7 #include "quote.h"
8 #include "pathspec.h"
9 #include "dir.h"
10 #include "submodule.h"
11 #include "submodule-config.h"
12 #include "string-list.h"
13 #include "run-command.h"
14 #include "remote.h"
15 #include "refs.h"
16 #include "refspec.h"
17 #include "connect.h"
18 #include "revision.h"
19 #include "diffcore.h"
20 #include "diff.h"
21 #include "object-store.h"
22 #include "advice.h"
23 #include "branch.h"
24 #include "list-objects-filter-options.h"
25
26 #define OPT_QUIET (1 << 0)
27 #define OPT_CACHED (1 << 1)
28 #define OPT_RECURSIVE (1 << 2)
29 #define OPT_FORCE (1 << 3)
30
31 typedef void (*each_submodule_fn)(const struct cache_entry *list_item,
32 void *cb_data);
33
34 static int repo_get_default_remote(struct repository *repo, char **default_remote)
35 {
36 char *dest = NULL;
37 struct strbuf sb = STRBUF_INIT;
38 struct ref_store *store = get_main_ref_store(repo);
39 const char *refname = refs_resolve_ref_unsafe(store, "HEAD", 0, NULL,
40 NULL);
41
42 if (!refname)
43 return die_message(_("No such ref: %s"), "HEAD");
44
45 /* detached HEAD */
46 if (!strcmp(refname, "HEAD")) {
47 *default_remote = xstrdup("origin");
48 return 0;
49 }
50
51 if (!skip_prefix(refname, "refs/heads/", &refname))
52 return die_message(_("Expecting a full ref name, got %s"),
53 refname);
54
55 strbuf_addf(&sb, "branch.%s.remote", refname);
56 if (repo_config_get_string(repo, sb.buf, &dest))
57 *default_remote = xstrdup("origin");
58 else
59 *default_remote = dest;
60
61 strbuf_release(&sb);
62 return 0;
63 }
64
65 static int get_default_remote_submodule(const char *module_path, char **default_remote)
66 {
67 struct repository subrepo;
68 int ret;
69
70 if (repo_submodule_init(&subrepo, the_repository, module_path,
71 null_oid()) < 0)
72 return die_message(_("could not get a repository handle for submodule '%s'"),
73 module_path);
74 ret = repo_get_default_remote(&subrepo, default_remote);
75 repo_clear(&subrepo);
76
77 return ret;
78 }
79
80 static char *get_default_remote(void)
81 {
82 char *default_remote;
83 int code = repo_get_default_remote(the_repository, &default_remote);
84
85 if (code)
86 exit(code);
87
88 return default_remote;
89 }
90
91 static char *resolve_relative_url(const char *rel_url, const char *up_path, int quiet)
92 {
93 char *remoteurl, *resolved_url;
94 char *remote = get_default_remote();
95 struct strbuf remotesb = STRBUF_INIT;
96
97 strbuf_addf(&remotesb, "remote.%s.url", remote);
98 if (git_config_get_string(remotesb.buf, &remoteurl)) {
99 if (!quiet)
100 warning(_("could not look up configuration '%s'. "
101 "Assuming this repository is its own "
102 "authoritative upstream."),
103 remotesb.buf);
104 remoteurl = xgetcwd();
105 }
106 resolved_url = relative_url(remoteurl, rel_url, up_path);
107
108 free(remote);
109 free(remoteurl);
110 strbuf_release(&remotesb);
111
112 return resolved_url;
113 }
114
115 /* the result should be freed by the caller. */
116 static char *get_submodule_displaypath(const char *path, const char *prefix,
117 const char *super_prefix)
118 {
119 if (prefix && super_prefix) {
120 BUG("cannot have prefix '%s' and superprefix '%s'",
121 prefix, super_prefix);
122 } else if (prefix) {
123 struct strbuf sb = STRBUF_INIT;
124 char *displaypath = xstrdup(relative_path(path, prefix, &sb));
125 strbuf_release(&sb);
126 return displaypath;
127 } else if (super_prefix) {
128 return xstrfmt("%s%s", super_prefix, path);
129 } else {
130 return xstrdup(path);
131 }
132 }
133
134 static char *compute_rev_name(const char *sub_path, const char* object_id)
135 {
136 struct strbuf sb = STRBUF_INIT;
137 const char ***d;
138
139 static const char *describe_bare[] = { NULL };
140
141 static const char *describe_tags[] = { "--tags", NULL };
142
143 static const char *describe_contains[] = { "--contains", NULL };
144
145 static const char *describe_all_always[] = { "--all", "--always", NULL };
146
147 static const char **describe_argv[] = { describe_bare, describe_tags,
148 describe_contains,
149 describe_all_always, NULL };
150
151 for (d = describe_argv; *d; d++) {
152 struct child_process cp = CHILD_PROCESS_INIT;
153 prepare_submodule_repo_env(&cp.env);
154 cp.dir = sub_path;
155 cp.git_cmd = 1;
156 cp.no_stderr = 1;
157
158 strvec_push(&cp.args, "describe");
159 strvec_pushv(&cp.args, *d);
160 strvec_push(&cp.args, object_id);
161
162 if (!capture_command(&cp, &sb, 0)) {
163 strbuf_strip_suffix(&sb, "\n");
164 return strbuf_detach(&sb, NULL);
165 }
166 }
167
168 strbuf_release(&sb);
169 return NULL;
170 }
171
172 struct module_list {
173 const struct cache_entry **entries;
174 int alloc, nr;
175 };
176 #define MODULE_LIST_INIT { 0 }
177
178 static void module_list_release(struct module_list *ml)
179 {
180 free(ml->entries);
181 }
182
183 static int module_list_compute(const char **argv,
184 const char *prefix,
185 struct pathspec *pathspec,
186 struct module_list *list)
187 {
188 int i, result = 0;
189 char *ps_matched = NULL;
190
191 parse_pathspec(pathspec, 0,
192 PATHSPEC_PREFER_FULL,
193 prefix, argv);
194
195 if (pathspec->nr)
196 ps_matched = xcalloc(pathspec->nr, 1);
197
198 if (repo_read_index(the_repository) < 0)
199 die(_("index file corrupt"));
200
201 for (i = 0; i < the_index.cache_nr; i++) {
202 const struct cache_entry *ce = the_index.cache[i];
203
204 if (!match_pathspec(&the_index, pathspec, ce->name, ce_namelen(ce),
205 0, ps_matched, 1) ||
206 !S_ISGITLINK(ce->ce_mode))
207 continue;
208
209 ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
210 list->entries[list->nr++] = ce;
211 while (i + 1 < the_index.cache_nr &&
212 !strcmp(ce->name, the_index.cache[i + 1]->name))
213 /*
214 * Skip entries with the same name in different stages
215 * to make sure an entry is returned only once.
216 */
217 i++;
218 }
219
220 if (ps_matched && report_path_error(ps_matched, pathspec))
221 result = -1;
222
223 free(ps_matched);
224
225 return result;
226 }
227
228 static void module_list_active(struct module_list *list)
229 {
230 int i;
231 struct module_list active_modules = MODULE_LIST_INIT;
232
233 for (i = 0; i < list->nr; i++) {
234 const struct cache_entry *ce = list->entries[i];
235
236 if (!is_submodule_active(the_repository, ce->name))
237 continue;
238
239 ALLOC_GROW(active_modules.entries,
240 active_modules.nr + 1,
241 active_modules.alloc);
242 active_modules.entries[active_modules.nr++] = ce;
243 }
244
245 module_list_release(list);
246 *list = active_modules;
247 }
248
249 static char *get_up_path(const char *path)
250 {
251 int i;
252 struct strbuf sb = STRBUF_INIT;
253
254 for (i = count_slashes(path); i; i--)
255 strbuf_addstr(&sb, "../");
256
257 /*
258 * Check if 'path' ends with slash or not
259 * for having the same output for dir/sub_dir
260 * and dir/sub_dir/
261 */
262 if (!is_dir_sep(path[strlen(path) - 1]))
263 strbuf_addstr(&sb, "../");
264
265 return strbuf_detach(&sb, NULL);
266 }
267
268 static void for_each_listed_submodule(const struct module_list *list,
269 each_submodule_fn fn, void *cb_data)
270 {
271 int i;
272
273 for (i = 0; i < list->nr; i++)
274 fn(list->entries[i], cb_data);
275 }
276
277 struct foreach_cb {
278 int argc;
279 const char **argv;
280 const char *prefix;
281 const char *super_prefix;
282 int quiet;
283 int recursive;
284 };
285 #define FOREACH_CB_INIT { 0 }
286
287 static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
288 void *cb_data)
289 {
290 struct foreach_cb *info = cb_data;
291 const char *path = list_item->name;
292 const struct object_id *ce_oid = &list_item->oid;
293 const struct submodule *sub;
294 struct child_process cp = CHILD_PROCESS_INIT;
295 char *displaypath;
296
297 displaypath = get_submodule_displaypath(path, info->prefix,
298 info->super_prefix);
299
300 sub = submodule_from_path(the_repository, null_oid(), path);
301
302 if (!sub)
303 die(_("No url found for submodule path '%s' in .gitmodules"),
304 displaypath);
305
306 if (!is_submodule_populated_gently(path, NULL))
307 goto cleanup;
308
309 prepare_submodule_repo_env(&cp.env);
310
311 /*
312 * For the purpose of executing <command> in the submodule,
313 * separate shell is used for the purpose of running the
314 * child process.
315 */
316 cp.use_shell = 1;
317 cp.dir = path;
318
319 /*
320 * NEEDSWORK: the command currently has access to the variables $name,
321 * $sm_path, $displaypath, $sha1 and $toplevel only when the command
322 * contains a single argument. This is done for maintaining a faithful
323 * translation from shell script.
324 */
325 if (info->argc == 1) {
326 char *toplevel = xgetcwd();
327 struct strbuf sb = STRBUF_INIT;
328
329 strvec_pushf(&cp.env, "name=%s", sub->name);
330 strvec_pushf(&cp.env, "sm_path=%s", path);
331 strvec_pushf(&cp.env, "displaypath=%s", displaypath);
332 strvec_pushf(&cp.env, "sha1=%s",
333 oid_to_hex(ce_oid));
334 strvec_pushf(&cp.env, "toplevel=%s", toplevel);
335
336 /*
337 * Since the path variable was accessible from the script
338 * before porting, it is also made available after porting.
339 * The environment variable "PATH" has a very special purpose
340 * on windows. And since environment variables are
341 * case-insensitive in windows, it interferes with the
342 * existing PATH variable. Hence, to avoid that, we expose
343 * path via the args strvec and not via env.
344 */
345 sq_quote_buf(&sb, path);
346 strvec_pushf(&cp.args, "path=%s; %s",
347 sb.buf, info->argv[0]);
348 strbuf_release(&sb);
349 free(toplevel);
350 } else {
351 strvec_pushv(&cp.args, info->argv);
352 }
353
354 if (!info->quiet)
355 printf(_("Entering '%s'\n"), displaypath);
356
357 if (info->argv[0] && run_command(&cp))
358 die(_("run_command returned non-zero status for %s\n."),
359 displaypath);
360
361 if (info->recursive) {
362 struct child_process cpr = CHILD_PROCESS_INIT;
363
364 cpr.git_cmd = 1;
365 cpr.dir = path;
366 prepare_submodule_repo_env(&cpr.env);
367
368 strvec_pushl(&cpr.args, "submodule--helper", "foreach", "--recursive",
369 NULL);
370 strvec_pushl(&cpr.args, "--super-prefix", NULL);
371 strvec_pushf(&cpr.args, "%s/", displaypath);
372
373 if (info->quiet)
374 strvec_push(&cpr.args, "--quiet");
375
376 strvec_push(&cpr.args, "--");
377 strvec_pushv(&cpr.args, info->argv);
378
379 if (run_command(&cpr))
380 die(_("run_command returned non-zero status while "
381 "recursing in the nested submodules of %s\n."),
382 displaypath);
383 }
384
385 cleanup:
386 free(displaypath);
387 }
388
389 static int module_foreach(int argc, const char **argv, const char *prefix)
390 {
391 struct foreach_cb info = FOREACH_CB_INIT;
392 struct pathspec pathspec = { 0 };
393 struct module_list list = MODULE_LIST_INIT;
394 struct option module_foreach_options[] = {
395 OPT__SUPER_PREFIX(&info.super_prefix),
396 OPT__QUIET(&info.quiet, N_("suppress output of entering each submodule command")),
397 OPT_BOOL(0, "recursive", &info.recursive,
398 N_("recurse into nested submodules")),
399 OPT_END()
400 };
401 const char *const git_submodule_helper_usage[] = {
402 N_("git submodule foreach [--quiet] [--recursive] [--] <command>"),
403 NULL
404 };
405 int ret = 1;
406
407 argc = parse_options(argc, argv, prefix, module_foreach_options,
408 git_submodule_helper_usage, 0);
409
410 if (module_list_compute(NULL, prefix, &pathspec, &list) < 0)
411 goto cleanup;
412
413 info.argc = argc;
414 info.argv = argv;
415 info.prefix = prefix;
416
417 for_each_listed_submodule(&list, runcommand_in_submodule_cb, &info);
418
419 ret = 0;
420 cleanup:
421 module_list_release(&list);
422 clear_pathspec(&pathspec);
423 return ret;
424 }
425
426 static int starts_with_dot_slash(const char *const path)
427 {
428 return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_SLASH |
429 PATH_MATCH_XPLATFORM);
430 }
431
432 static int starts_with_dot_dot_slash(const char *const path)
433 {
434 return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH |
435 PATH_MATCH_XPLATFORM);
436 }
437
438 struct init_cb {
439 const char *prefix;
440 const char *super_prefix;
441 unsigned int flags;
442 };
443 #define INIT_CB_INIT { 0 }
444
445 static void init_submodule(const char *path, const char *prefix,
446 const char *super_prefix,
447 unsigned int flags)
448 {
449 const struct submodule *sub;
450 struct strbuf sb = STRBUF_INIT;
451 const char *upd;
452 char *url = NULL, *displaypath;
453
454 displaypath = get_submodule_displaypath(path, prefix, super_prefix);
455
456 sub = submodule_from_path(the_repository, null_oid(), path);
457
458 if (!sub)
459 die(_("No url found for submodule path '%s' in .gitmodules"),
460 displaypath);
461
462 /*
463 * NEEDSWORK: In a multi-working-tree world, this needs to be
464 * set in the per-worktree config.
465 *
466 * Set active flag for the submodule being initialized
467 */
468 if (!is_submodule_active(the_repository, path)) {
469 strbuf_addf(&sb, "submodule.%s.active", sub->name);
470 git_config_set_gently(sb.buf, "true");
471 strbuf_reset(&sb);
472 }
473
474 /*
475 * Copy url setting when it is not set yet.
476 * To look up the url in .git/config, we must not fall back to
477 * .gitmodules, so look it up directly.
478 */
479 strbuf_addf(&sb, "submodule.%s.url", sub->name);
480 if (git_config_get_string(sb.buf, &url)) {
481 if (!sub->url)
482 die(_("No url found for submodule path '%s' in .gitmodules"),
483 displaypath);
484
485 url = xstrdup(sub->url);
486
487 /* Possibly a url relative to parent */
488 if (starts_with_dot_dot_slash(url) ||
489 starts_with_dot_slash(url)) {
490 char *oldurl = url;
491
492 url = resolve_relative_url(oldurl, NULL, 0);
493 free(oldurl);
494 }
495
496 if (git_config_set_gently(sb.buf, url))
497 die(_("Failed to register url for submodule path '%s'"),
498 displaypath);
499 if (!(flags & OPT_QUIET))
500 fprintf(stderr,
501 _("Submodule '%s' (%s) registered for path '%s'\n"),
502 sub->name, url, displaypath);
503 }
504 strbuf_reset(&sb);
505
506 /* Copy "update" setting when it is not set yet */
507 strbuf_addf(&sb, "submodule.%s.update", sub->name);
508 if (git_config_get_string_tmp(sb.buf, &upd) &&
509 sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
510 if (sub->update_strategy.type == SM_UPDATE_COMMAND) {
511 fprintf(stderr, _("warning: command update mode suggested for submodule '%s'\n"),
512 sub->name);
513 upd = "none";
514 } else {
515 upd = submodule_update_type_to_string(sub->update_strategy.type);
516 }
517
518 if (git_config_set_gently(sb.buf, upd))
519 die(_("Failed to register update mode for submodule path '%s'"), displaypath);
520 }
521 strbuf_release(&sb);
522 free(displaypath);
523 free(url);
524 }
525
526 static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data)
527 {
528 struct init_cb *info = cb_data;
529
530 init_submodule(list_item->name, info->prefix, info->super_prefix,
531 info->flags);
532 }
533
534 static int module_init(int argc, const char **argv, const char *prefix)
535 {
536 struct init_cb info = INIT_CB_INIT;
537 struct pathspec pathspec = { 0 };
538 struct module_list list = MODULE_LIST_INIT;
539 int quiet = 0;
540 struct option module_init_options[] = {
541 OPT__QUIET(&quiet, N_("suppress output for initializing a submodule")),
542 OPT_END()
543 };
544 const char *const git_submodule_helper_usage[] = {
545 N_("git submodule init [<options>] [<path>]"),
546 NULL
547 };
548 int ret = 1;
549
550 argc = parse_options(argc, argv, prefix, module_init_options,
551 git_submodule_helper_usage, 0);
552
553 if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
554 goto cleanup;
555
556 /*
557 * If there are no path args and submodule.active is set then,
558 * by default, only initialize 'active' modules.
559 */
560 if (!argc && git_config_get_value_multi("submodule.active"))
561 module_list_active(&list);
562
563 info.prefix = prefix;
564 if (quiet)
565 info.flags |= OPT_QUIET;
566
567 for_each_listed_submodule(&list, init_submodule_cb, &info);
568
569 ret = 0;
570 cleanup:
571 module_list_release(&list);
572 clear_pathspec(&pathspec);
573 return ret;
574 }
575
576 struct status_cb {
577 const char *prefix;
578 const char *super_prefix;
579 unsigned int flags;
580 };
581 #define STATUS_CB_INIT { 0 }
582
583 static void print_status(unsigned int flags, char state, const char *path,
584 const struct object_id *oid, const char *displaypath)
585 {
586 if (flags & OPT_QUIET)
587 return;
588
589 printf("%c%s %s", state, oid_to_hex(oid), displaypath);
590
591 if (state == ' ' || state == '+') {
592 char *name = compute_rev_name(path, oid_to_hex(oid));
593
594 if (name)
595 printf(" (%s)", name);
596 free(name);
597 }
598
599 printf("\n");
600 }
601
602 static int handle_submodule_head_ref(const char *refname UNUSED,
603 const struct object_id *oid,
604 int flags UNUSED,
605 void *cb_data)
606 {
607 struct object_id *output = cb_data;
608
609 if (oid)
610 oidcpy(output, oid);
611
612 return 0;
613 }
614
615 static void status_submodule(const char *path, const struct object_id *ce_oid,
616 unsigned int ce_flags, const char *prefix,
617 const char *super_prefix, unsigned int flags)
618 {
619 char *displaypath;
620 struct strvec diff_files_args = STRVEC_INIT;
621 struct rev_info rev = REV_INFO_INIT;
622 int diff_files_result;
623 struct strbuf buf = STRBUF_INIT;
624 const char *git_dir;
625 struct setup_revision_opt opt = {
626 .free_removed_argv_elements = 1,
627 };
628
629 if (!submodule_from_path(the_repository, null_oid(), path))
630 die(_("no submodule mapping found in .gitmodules for path '%s'"),
631 path);
632
633 displaypath = get_submodule_displaypath(path, prefix, super_prefix);
634
635 if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) {
636 print_status(flags, 'U', path, null_oid(), displaypath);
637 goto cleanup;
638 }
639
640 strbuf_addf(&buf, "%s/.git", path);
641 git_dir = read_gitfile(buf.buf);
642 if (!git_dir)
643 git_dir = buf.buf;
644
645 if (!is_submodule_active(the_repository, path) ||
646 !is_git_directory(git_dir)) {
647 print_status(flags, '-', path, ce_oid, displaypath);
648 strbuf_release(&buf);
649 goto cleanup;
650 }
651 strbuf_release(&buf);
652
653 strvec_pushl(&diff_files_args, "diff-files",
654 "--ignore-submodules=dirty", "--quiet", "--",
655 path, NULL);
656
657 git_config(git_diff_basic_config, NULL);
658
659 repo_init_revisions(the_repository, &rev, NULL);
660 rev.abbrev = 0;
661 setup_revisions(diff_files_args.nr, diff_files_args.v, &rev, &opt);
662 diff_files_result = run_diff_files(&rev, 0);
663
664 if (!diff_result_code(&rev.diffopt, diff_files_result)) {
665 print_status(flags, ' ', path, ce_oid,
666 displaypath);
667 } else if (!(flags & OPT_CACHED)) {
668 struct object_id oid;
669 struct ref_store *refs = get_submodule_ref_store(path);
670
671 if (!refs) {
672 print_status(flags, '-', path, ce_oid, displaypath);
673 goto cleanup;
674 }
675 if (refs_head_ref(refs, handle_submodule_head_ref, &oid))
676 die(_("could not resolve HEAD ref inside the "
677 "submodule '%s'"), path);
678
679 print_status(flags, '+', path, &oid, displaypath);
680 } else {
681 print_status(flags, '+', path, ce_oid, displaypath);
682 }
683
684 if (flags & OPT_RECURSIVE) {
685 struct child_process cpr = CHILD_PROCESS_INIT;
686
687 cpr.git_cmd = 1;
688 cpr.dir = path;
689 prepare_submodule_repo_env(&cpr.env);
690
691 strvec_pushl(&cpr.args, "submodule--helper", "status",
692 "--recursive", NULL);
693 strvec_push(&cpr.args, "--super-prefix");
694 strvec_pushf(&cpr.args, "%s/", displaypath);
695
696 if (flags & OPT_CACHED)
697 strvec_push(&cpr.args, "--cached");
698
699 if (flags & OPT_QUIET)
700 strvec_push(&cpr.args, "--quiet");
701
702 if (run_command(&cpr))
703 die(_("failed to recurse into submodule '%s'"), path);
704 }
705
706 cleanup:
707 strvec_clear(&diff_files_args);
708 free(displaypath);
709 release_revisions(&rev);
710 }
711
712 static void status_submodule_cb(const struct cache_entry *list_item,
713 void *cb_data)
714 {
715 struct status_cb *info = cb_data;
716
717 status_submodule(list_item->name, &list_item->oid, list_item->ce_flags,
718 info->prefix, info->super_prefix, info->flags);
719 }
720
721 static int module_status(int argc, const char **argv, const char *prefix)
722 {
723 struct status_cb info = STATUS_CB_INIT;
724 struct pathspec pathspec = { 0 };
725 struct module_list list = MODULE_LIST_INIT;
726 int quiet = 0;
727 struct option module_status_options[] = {
728 OPT__SUPER_PREFIX(&info.super_prefix),
729 OPT__QUIET(&quiet, N_("suppress submodule status output")),
730 OPT_BIT(0, "cached", &info.flags, N_("use commit stored in the index instead of the one stored in the submodule HEAD"), OPT_CACHED),
731 OPT_BIT(0, "recursive", &info.flags, N_("recurse into nested submodules"), OPT_RECURSIVE),
732 OPT_END()
733 };
734 const char *const git_submodule_helper_usage[] = {
735 N_("git submodule status [--quiet] [--cached] [--recursive] [<path>...]"),
736 NULL
737 };
738 int ret = 1;
739
740 argc = parse_options(argc, argv, prefix, module_status_options,
741 git_submodule_helper_usage, 0);
742
743 if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
744 goto cleanup;
745
746 info.prefix = prefix;
747 if (quiet)
748 info.flags |= OPT_QUIET;
749
750 for_each_listed_submodule(&list, status_submodule_cb, &info);
751
752 ret = 0;
753 cleanup:
754 module_list_release(&list);
755 clear_pathspec(&pathspec);
756 return ret;
757 }
758
759 struct module_cb {
760 unsigned int mod_src;
761 unsigned int mod_dst;
762 struct object_id oid_src;
763 struct object_id oid_dst;
764 char status;
765 char *sm_path;
766 };
767 #define MODULE_CB_INIT { 0 }
768
769 static void module_cb_release(struct module_cb *mcb)
770 {
771 free(mcb->sm_path);
772 }
773
774 struct module_cb_list {
775 struct module_cb **entries;
776 int alloc, nr;
777 };
778 #define MODULE_CB_LIST_INIT { 0 }
779
780 static void module_cb_list_release(struct module_cb_list *mcbl)
781 {
782 int i;
783
784 for (i = 0; i < mcbl->nr; i++) {
785 struct module_cb *mcb = mcbl->entries[i];
786
787 module_cb_release(mcb);
788 free(mcb);
789 }
790 free(mcbl->entries);
791 }
792
793 struct summary_cb {
794 int argc;
795 const char **argv;
796 const char *prefix;
797 const char *super_prefix;
798 unsigned int cached: 1;
799 unsigned int for_status: 1;
800 unsigned int files: 1;
801 int summary_limit;
802 };
803 #define SUMMARY_CB_INIT { 0 }
804
805 enum diff_cmd {
806 DIFF_INDEX,
807 DIFF_FILES
808 };
809
810 static char *verify_submodule_committish(const char *sm_path,
811 const char *committish)
812 {
813 struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
814 struct strbuf result = STRBUF_INIT;
815
816 cp_rev_parse.git_cmd = 1;
817 cp_rev_parse.dir = sm_path;
818 prepare_submodule_repo_env(&cp_rev_parse.env);
819 strvec_pushl(&cp_rev_parse.args, "rev-parse", "-q", "--short", NULL);
820 strvec_pushf(&cp_rev_parse.args, "%s^0", committish);
821 strvec_push(&cp_rev_parse.args, "--");
822
823 if (capture_command(&cp_rev_parse, &result, 0))
824 return NULL;
825
826 strbuf_trim_trailing_newline(&result);
827 return strbuf_detach(&result, NULL);
828 }
829
830 static void print_submodule_summary(struct summary_cb *info, const char *errmsg,
831 int total_commits, const char *displaypath,
832 const char *src_abbrev, const char *dst_abbrev,
833 struct module_cb *p)
834 {
835 if (p->status == 'T') {
836 if (S_ISGITLINK(p->mod_dst))
837 printf(_("* %s %s(blob)->%s(submodule)"),
838 displaypath, src_abbrev, dst_abbrev);
839 else
840 printf(_("* %s %s(submodule)->%s(blob)"),
841 displaypath, src_abbrev, dst_abbrev);
842 } else {
843 printf("* %s %s...%s",
844 displaypath, src_abbrev, dst_abbrev);
845 }
846
847 if (total_commits < 0)
848 printf(":\n");
849 else
850 printf(" (%d):\n", total_commits);
851
852 if (errmsg) {
853 printf(_("%s"), errmsg);
854 } else if (total_commits > 0) {
855 struct child_process cp_log = CHILD_PROCESS_INIT;
856
857 cp_log.git_cmd = 1;
858 cp_log.dir = p->sm_path;
859 prepare_submodule_repo_env(&cp_log.env);
860 strvec_pushl(&cp_log.args, "log", NULL);
861
862 if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) {
863 if (info->summary_limit > 0)
864 strvec_pushf(&cp_log.args, "-%d",
865 info->summary_limit);
866
867 strvec_pushl(&cp_log.args, "--pretty= %m %s",
868 "--first-parent", NULL);
869 strvec_pushf(&cp_log.args, "%s...%s",
870 src_abbrev, dst_abbrev);
871 } else if (S_ISGITLINK(p->mod_dst)) {
872 strvec_pushl(&cp_log.args, "--pretty= > %s",
873 "-1", dst_abbrev, NULL);
874 } else {
875 strvec_pushl(&cp_log.args, "--pretty= < %s",
876 "-1", src_abbrev, NULL);
877 }
878 run_command(&cp_log);
879 }
880 printf("\n");
881 }
882
883 static void generate_submodule_summary(struct summary_cb *info,
884 struct module_cb *p)
885 {
886 char *displaypath, *src_abbrev = NULL, *dst_abbrev;
887 int missing_src = 0, missing_dst = 0;
888 struct strbuf errmsg = STRBUF_INIT;
889 int total_commits = -1;
890
891 if (!info->cached && oideq(&p->oid_dst, null_oid())) {
892 if (S_ISGITLINK(p->mod_dst)) {
893 struct ref_store *refs = get_submodule_ref_store(p->sm_path);
894
895 if (refs)
896 refs_head_ref(refs, handle_submodule_head_ref, &p->oid_dst);
897 } else if (S_ISLNK(p->mod_dst) || S_ISREG(p->mod_dst)) {
898 struct stat st;
899 int fd = open(p->sm_path, O_RDONLY);
900
901 if (fd < 0 || fstat(fd, &st) < 0 ||
902 index_fd(&the_index, &p->oid_dst, fd, &st, OBJ_BLOB,
903 p->sm_path, 0))
904 error(_("couldn't hash object from '%s'"), p->sm_path);
905 } else {
906 /* for a submodule removal (mode:0000000), don't warn */
907 if (p->mod_dst)
908 warning(_("unexpected mode %o\n"), p->mod_dst);
909 }
910 }
911
912 if (S_ISGITLINK(p->mod_src)) {
913 if (p->status != 'D')
914 src_abbrev = verify_submodule_committish(p->sm_path,
915 oid_to_hex(&p->oid_src));
916 if (!src_abbrev) {
917 missing_src = 1;
918 /*
919 * As `rev-parse` failed, we fallback to getting
920 * the abbreviated hash using oid_src. We do
921 * this as we might still need the abbreviated
922 * hash in cases like a submodule type change, etc.
923 */
924 src_abbrev = xstrndup(oid_to_hex(&p->oid_src), 7);
925 }
926 } else {
927 /*
928 * The source does not point to a submodule.
929 * So, we fallback to getting the abbreviation using
930 * oid_src as we might still need the abbreviated
931 * hash in cases like submodule add, etc.
932 */
933 src_abbrev = xstrndup(oid_to_hex(&p->oid_src), 7);
934 }
935
936 if (S_ISGITLINK(p->mod_dst)) {
937 dst_abbrev = verify_submodule_committish(p->sm_path,
938 oid_to_hex(&p->oid_dst));
939 if (!dst_abbrev) {
940 missing_dst = 1;
941 /*
942 * As `rev-parse` failed, we fallback to getting
943 * the abbreviated hash using oid_dst. We do
944 * this as we might still need the abbreviated
945 * hash in cases like a submodule type change, etc.
946 */
947 dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
948 }
949 } else {
950 /*
951 * The destination does not point to a submodule.
952 * So, we fallback to getting the abbreviation using
953 * oid_dst as we might still need the abbreviated
954 * hash in cases like a submodule removal, etc.
955 */
956 dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
957 }
958
959 displaypath = get_submodule_displaypath(p->sm_path, info->prefix,
960 info->super_prefix);
961
962 if (!missing_src && !missing_dst) {
963 struct child_process cp_rev_list = CHILD_PROCESS_INIT;
964 struct strbuf sb_rev_list = STRBUF_INIT;
965
966 strvec_pushl(&cp_rev_list.args, "rev-list",
967 "--first-parent", "--count", NULL);
968 if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst))
969 strvec_pushf(&cp_rev_list.args, "%s...%s",
970 src_abbrev, dst_abbrev);
971 else
972 strvec_push(&cp_rev_list.args, S_ISGITLINK(p->mod_src) ?
973 src_abbrev : dst_abbrev);
974 strvec_push(&cp_rev_list.args, "--");
975
976 cp_rev_list.git_cmd = 1;
977 cp_rev_list.dir = p->sm_path;
978 prepare_submodule_repo_env(&cp_rev_list.env);
979
980 if (!capture_command(&cp_rev_list, &sb_rev_list, 0))
981 total_commits = atoi(sb_rev_list.buf);
982
983 strbuf_release(&sb_rev_list);
984 } else {
985 /*
986 * Don't give error msg for modification whose dst is not
987 * submodule, i.e., deleted or changed to blob
988 */
989 if (S_ISGITLINK(p->mod_dst)) {
990 if (missing_src && missing_dst) {
991 strbuf_addf(&errmsg, " Warn: %s doesn't contain commits %s and %s\n",
992 displaypath, oid_to_hex(&p->oid_src),
993 oid_to_hex(&p->oid_dst));
994 } else {
995 strbuf_addf(&errmsg, " Warn: %s doesn't contain commit %s\n",
996 displaypath, missing_src ?
997 oid_to_hex(&p->oid_src) :
998 oid_to_hex(&p->oid_dst));
999 }
1000 }
1001 }
1002
1003 print_submodule_summary(info, errmsg.len ? errmsg.buf : NULL,
1004 total_commits, displaypath, src_abbrev,
1005 dst_abbrev, p);
1006
1007 free(displaypath);
1008 free(src_abbrev);
1009 free(dst_abbrev);
1010 strbuf_release(&errmsg);
1011 }
1012
1013 static void prepare_submodule_summary(struct summary_cb *info,
1014 struct module_cb_list *list)
1015 {
1016 int i;
1017 for (i = 0; i < list->nr; i++) {
1018 const struct submodule *sub;
1019 struct module_cb *p = list->entries[i];
1020 struct strbuf sm_gitdir = STRBUF_INIT;
1021
1022 if (p->status == 'D' || p->status == 'T') {
1023 generate_submodule_summary(info, p);
1024 continue;
1025 }
1026
1027 if (info->for_status && p->status != 'A' &&
1028 (sub = submodule_from_path(the_repository,
1029 null_oid(), p->sm_path))) {
1030 char *config_key = NULL;
1031 const char *value;
1032 int ignore_all = 0;
1033
1034 config_key = xstrfmt("submodule.%s.ignore",
1035 sub->name);
1036 if (!git_config_get_string_tmp(config_key, &value))
1037 ignore_all = !strcmp(value, "all");
1038 else if (sub->ignore)
1039 ignore_all = !strcmp(sub->ignore, "all");
1040
1041 free(config_key);
1042 if (ignore_all)
1043 continue;
1044 }
1045
1046 /* Also show added or modified modules which are checked out */
1047 strbuf_addstr(&sm_gitdir, p->sm_path);
1048 if (is_nonbare_repository_dir(&sm_gitdir))
1049 generate_submodule_summary(info, p);
1050 strbuf_release(&sm_gitdir);
1051 }
1052 }
1053
1054 static void submodule_summary_callback(struct diff_queue_struct *q,
1055 struct diff_options *options UNUSED,
1056 void *data)
1057 {
1058 int i;
1059 struct module_cb_list *list = data;
1060 for (i = 0; i < q->nr; i++) {
1061 struct diff_filepair *p = q->queue[i];
1062 struct module_cb *temp;
1063
1064 if (!S_ISGITLINK(p->one->mode) && !S_ISGITLINK(p->two->mode))
1065 continue;
1066 temp = (struct module_cb*)malloc(sizeof(struct module_cb));
1067 temp->mod_src = p->one->mode;
1068 temp->mod_dst = p->two->mode;
1069 temp->oid_src = p->one->oid;
1070 temp->oid_dst = p->two->oid;
1071 temp->status = p->status;
1072 temp->sm_path = xstrdup(p->one->path);
1073
1074 ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
1075 list->entries[list->nr++] = temp;
1076 }
1077 }
1078
1079 static const char *get_diff_cmd(enum diff_cmd diff_cmd)
1080 {
1081 switch (diff_cmd) {
1082 case DIFF_INDEX: return "diff-index";
1083 case DIFF_FILES: return "diff-files";
1084 default: BUG("bad diff_cmd value %d", diff_cmd);
1085 }
1086 }
1087
1088 static int compute_summary_module_list(struct object_id *head_oid,
1089 struct summary_cb *info,
1090 enum diff_cmd diff_cmd)
1091 {
1092 struct strvec diff_args = STRVEC_INIT;
1093 struct rev_info rev;
1094 struct setup_revision_opt opt = {
1095 .free_removed_argv_elements = 1,
1096 };
1097 struct module_cb_list list = MODULE_CB_LIST_INIT;
1098 int ret = 0;
1099
1100 strvec_push(&diff_args, get_diff_cmd(diff_cmd));
1101 if (info->cached)
1102 strvec_push(&diff_args, "--cached");
1103 strvec_pushl(&diff_args, "--ignore-submodules=dirty", "--raw", NULL);
1104 if (head_oid)
1105 strvec_push(&diff_args, oid_to_hex(head_oid));
1106 strvec_push(&diff_args, "--");
1107 if (info->argc)
1108 strvec_pushv(&diff_args, info->argv);
1109
1110 git_config(git_diff_basic_config, NULL);
1111 init_revisions(&rev, info->prefix);
1112 rev.abbrev = 0;
1113 precompose_argv_prefix(diff_args.nr, diff_args.v, NULL);
1114 setup_revisions(diff_args.nr, diff_args.v, &rev, &opt);
1115 rev.diffopt.output_format = DIFF_FORMAT_NO_OUTPUT | DIFF_FORMAT_CALLBACK;
1116 rev.diffopt.format_callback = submodule_summary_callback;
1117 rev.diffopt.format_callback_data = &list;
1118
1119 if (!info->cached) {
1120 if (diff_cmd == DIFF_INDEX)
1121 setup_work_tree();
1122 if (repo_read_index_preload(the_repository, &rev.diffopt.pathspec, 0) < 0) {
1123 perror("repo_read_index_preload");
1124 ret = -1;
1125 goto cleanup;
1126 }
1127 } else if (repo_read_index(the_repository) < 0) {
1128 perror("repo_read_cache");
1129 ret = -1;
1130 goto cleanup;
1131 }
1132
1133 if (diff_cmd == DIFF_INDEX)
1134 run_diff_index(&rev, info->cached);
1135 else
1136 run_diff_files(&rev, 0);
1137 prepare_submodule_summary(info, &list);
1138 cleanup:
1139 strvec_clear(&diff_args);
1140 release_revisions(&rev);
1141 module_cb_list_release(&list);
1142 return ret;
1143 }
1144
1145 static int module_summary(int argc, const char **argv, const char *prefix)
1146 {
1147 struct summary_cb info = SUMMARY_CB_INIT;
1148 int cached = 0;
1149 int for_status = 0;
1150 int files = 0;
1151 int summary_limit = -1;
1152 enum diff_cmd diff_cmd = DIFF_INDEX;
1153 struct object_id head_oid;
1154 int ret;
1155 struct option module_summary_options[] = {
1156 OPT_BOOL(0, "cached", &cached,
1157 N_("use the commit stored in the index instead of the submodule HEAD")),
1158 OPT_BOOL(0, "files", &files,
1159 N_("compare the commit in the index with that in the submodule HEAD")),
1160 OPT_BOOL(0, "for-status", &for_status,
1161 N_("skip submodules with 'ignore_config' value set to 'all'")),
1162 OPT_INTEGER('n', "summary-limit", &summary_limit,
1163 N_("limit the summary size")),
1164 OPT_END()
1165 };
1166 const char *const git_submodule_helper_usage[] = {
1167 N_("git submodule summary [<options>] [<commit>] [--] [<path>]"),
1168 NULL
1169 };
1170
1171 argc = parse_options(argc, argv, prefix, module_summary_options,
1172 git_submodule_helper_usage, 0);
1173
1174 if (!summary_limit)
1175 return 0;
1176
1177 if (!get_oid(argc ? argv[0] : "HEAD", &head_oid)) {
1178 if (argc) {
1179 argv++;
1180 argc--;
1181 }
1182 } else if (!argc || !strcmp(argv[0], "HEAD")) {
1183 /* before the first commit: compare with an empty tree */
1184 oidcpy(&head_oid, the_hash_algo->empty_tree);
1185 if (argc) {
1186 argv++;
1187 argc--;
1188 }
1189 } else {
1190 if (get_oid("HEAD", &head_oid))
1191 die(_("could not fetch a revision for HEAD"));
1192 }
1193
1194 if (files) {
1195 if (cached)
1196 die(_("options '%s' and '%s' cannot be used together"), "--cached", "--files");
1197 diff_cmd = DIFF_FILES;
1198 }
1199
1200 info.argc = argc;
1201 info.argv = argv;
1202 info.prefix = prefix;
1203 info.cached = !!cached;
1204 info.files = !!files;
1205 info.for_status = !!for_status;
1206 info.summary_limit = summary_limit;
1207
1208 ret = compute_summary_module_list((diff_cmd == DIFF_INDEX) ? &head_oid : NULL,
1209 &info, diff_cmd);
1210 return ret;
1211 }
1212
1213 struct sync_cb {
1214 const char *prefix;
1215 const char *super_prefix;
1216 unsigned int flags;
1217 };
1218 #define SYNC_CB_INIT { 0 }
1219
1220 static void sync_submodule(const char *path, const char *prefix,
1221 const char *super_prefix, unsigned int flags)
1222 {
1223 const struct submodule *sub;
1224 char *remote_key = NULL;
1225 char *sub_origin_url, *super_config_url, *displaypath, *default_remote;
1226 struct strbuf sb = STRBUF_INIT;
1227 char *sub_config_path = NULL;
1228 int code;
1229
1230 if (!is_submodule_active(the_repository, path))
1231 return;
1232
1233 sub = submodule_from_path(the_repository, null_oid(), path);
1234
1235 if (sub && sub->url) {
1236 if (starts_with_dot_dot_slash(sub->url) ||
1237 starts_with_dot_slash(sub->url)) {
1238 char *up_path = get_up_path(path);
1239
1240 sub_origin_url = resolve_relative_url(sub->url, up_path, 1);
1241 super_config_url = resolve_relative_url(sub->url, NULL, 1);
1242 free(up_path);
1243 } else {
1244 sub_origin_url = xstrdup(sub->url);
1245 super_config_url = xstrdup(sub->url);
1246 }
1247 } else {
1248 sub_origin_url = xstrdup("");
1249 super_config_url = xstrdup("");
1250 }
1251
1252 displaypath = get_submodule_displaypath(path, prefix, super_prefix);
1253
1254 if (!(flags & OPT_QUIET))
1255 printf(_("Synchronizing submodule url for '%s'\n"),
1256 displaypath);
1257
1258 strbuf_reset(&sb);
1259 strbuf_addf(&sb, "submodule.%s.url", sub->name);
1260 if (git_config_set_gently(sb.buf, super_config_url))
1261 die(_("failed to register url for submodule path '%s'"),
1262 displaypath);
1263
1264 if (!is_submodule_populated_gently(path, NULL))
1265 goto cleanup;
1266
1267 strbuf_reset(&sb);
1268 code = get_default_remote_submodule(path, &default_remote);
1269 if (code)
1270 exit(code);
1271
1272 remote_key = xstrfmt("remote.%s.url", default_remote);
1273 free(default_remote);
1274
1275 submodule_to_gitdir(&sb, path);
1276 strbuf_addstr(&sb, "/config");
1277
1278 if (git_config_set_in_file_gently(sb.buf, remote_key, sub_origin_url))
1279 die(_("failed to update remote for submodule '%s'"),
1280 path);
1281
1282 if (flags & OPT_RECURSIVE) {
1283 struct child_process cpr = CHILD_PROCESS_INIT;
1284
1285 cpr.git_cmd = 1;
1286 cpr.dir = path;
1287 prepare_submodule_repo_env(&cpr.env);
1288
1289 strvec_pushl(&cpr.args, "submodule--helper", "sync",
1290 "--recursive", NULL);
1291 strvec_push(&cpr.args, "--super-prefix");
1292 strvec_pushf(&cpr.args, "%s/", displaypath);
1293
1294
1295 if (flags & OPT_QUIET)
1296 strvec_push(&cpr.args, "--quiet");
1297
1298 if (run_command(&cpr))
1299 die(_("failed to recurse into submodule '%s'"),
1300 path);
1301 }
1302
1303 cleanup:
1304 free(super_config_url);
1305 free(sub_origin_url);
1306 strbuf_release(&sb);
1307 free(remote_key);
1308 free(displaypath);
1309 free(sub_config_path);
1310 }
1311
1312 static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data)
1313 {
1314 struct sync_cb *info = cb_data;
1315
1316 sync_submodule(list_item->name, info->prefix, info->super_prefix,
1317 info->flags);
1318 }
1319
1320 static int module_sync(int argc, const char **argv, const char *prefix)
1321 {
1322 struct sync_cb info = SYNC_CB_INIT;
1323 struct pathspec pathspec = { 0 };
1324 struct module_list list = MODULE_LIST_INIT;
1325 int quiet = 0;
1326 int recursive = 0;
1327 struct option module_sync_options[] = {
1328 OPT__SUPER_PREFIX(&info.super_prefix),
1329 OPT__QUIET(&quiet, N_("suppress output of synchronizing submodule url")),
1330 OPT_BOOL(0, "recursive", &recursive,
1331 N_("recurse into nested submodules")),
1332 OPT_END()
1333 };
1334 const char *const git_submodule_helper_usage[] = {
1335 N_("git submodule sync [--quiet] [--recursive] [<path>]"),
1336 NULL
1337 };
1338 int ret = 1;
1339
1340 argc = parse_options(argc, argv, prefix, module_sync_options,
1341 git_submodule_helper_usage, 0);
1342
1343 if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
1344 goto cleanup;
1345
1346 info.prefix = prefix;
1347 if (quiet)
1348 info.flags |= OPT_QUIET;
1349 if (recursive)
1350 info.flags |= OPT_RECURSIVE;
1351
1352 for_each_listed_submodule(&list, sync_submodule_cb, &info);
1353
1354 ret = 0;
1355 cleanup:
1356 module_list_release(&list);
1357 clear_pathspec(&pathspec);
1358 return ret;
1359 }
1360
1361 struct deinit_cb {
1362 const char *prefix;
1363 unsigned int flags;
1364 };
1365 #define DEINIT_CB_INIT { 0 }
1366
1367 static void deinit_submodule(const char *path, const char *prefix,
1368 unsigned int flags)
1369 {
1370 const struct submodule *sub;
1371 char *displaypath = NULL;
1372 struct child_process cp_config = CHILD_PROCESS_INIT;
1373 struct strbuf sb_config = STRBUF_INIT;
1374 char *sub_git_dir = xstrfmt("%s/.git", path);
1375
1376 sub = submodule_from_path(the_repository, null_oid(), path);
1377
1378 if (!sub || !sub->name)
1379 goto cleanup;
1380
1381 displaypath = get_submodule_displaypath(path, prefix, NULL);
1382
1383 /* remove the submodule work tree (unless the user already did it) */
1384 if (is_directory(path)) {
1385 struct strbuf sb_rm = STRBUF_INIT;
1386 const char *format;
1387
1388 if (is_directory(sub_git_dir)) {
1389 if (!(flags & OPT_QUIET))
1390 warning(_("Submodule work tree '%s' contains a .git "
1391 "directory. This will be replaced with a "
1392 ".git file by using absorbgitdirs."),
1393 displaypath);
1394
1395 absorb_git_dir_into_superproject(path, NULL);
1396
1397 }
1398
1399 if (!(flags & OPT_FORCE)) {
1400 struct child_process cp_rm = CHILD_PROCESS_INIT;
1401
1402 cp_rm.git_cmd = 1;
1403 strvec_pushl(&cp_rm.args, "rm", "-qn",
1404 path, NULL);
1405
1406 if (run_command(&cp_rm))
1407 die(_("Submodule work tree '%s' contains local "
1408 "modifications; use '-f' to discard them"),
1409 displaypath);
1410 }
1411
1412 strbuf_addstr(&sb_rm, path);
1413
1414 if (!remove_dir_recursively(&sb_rm, 0))
1415 format = _("Cleared directory '%s'\n");
1416 else
1417 format = _("Could not remove submodule work tree '%s'\n");
1418
1419 if (!(flags & OPT_QUIET))
1420 printf(format, displaypath);
1421
1422 submodule_unset_core_worktree(sub);
1423
1424 strbuf_release(&sb_rm);
1425 }
1426
1427 if (mkdir(path, 0777))
1428 printf(_("could not create empty submodule directory %s"),
1429 displaypath);
1430
1431 cp_config.git_cmd = 1;
1432 strvec_pushl(&cp_config.args, "config", "--get-regexp", NULL);
1433 strvec_pushf(&cp_config.args, "submodule.%s\\.", sub->name);
1434
1435 /* remove the .git/config entries (unless the user already did it) */
1436 if (!capture_command(&cp_config, &sb_config, 0) && sb_config.len) {
1437 char *sub_key = xstrfmt("submodule.%s", sub->name);
1438
1439 /*
1440 * remove the whole section so we have a clean state when
1441 * the user later decides to init this submodule again
1442 */
1443 git_config_rename_section_in_file(NULL, sub_key, NULL);
1444 if (!(flags & OPT_QUIET))
1445 printf(_("Submodule '%s' (%s) unregistered for path '%s'\n"),
1446 sub->name, sub->url, displaypath);
1447 free(sub_key);
1448 }
1449
1450 cleanup:
1451 free(displaypath);
1452 free(sub_git_dir);
1453 strbuf_release(&sb_config);
1454 }
1455
1456 static void deinit_submodule_cb(const struct cache_entry *list_item,
1457 void *cb_data)
1458 {
1459 struct deinit_cb *info = cb_data;
1460 deinit_submodule(list_item->name, info->prefix, info->flags);
1461 }
1462
1463 static int module_deinit(int argc, const char **argv, const char *prefix)
1464 {
1465 struct deinit_cb info = DEINIT_CB_INIT;
1466 struct pathspec pathspec = { 0 };
1467 struct module_list list = MODULE_LIST_INIT;
1468 int quiet = 0;
1469 int force = 0;
1470 int all = 0;
1471 struct option module_deinit_options[] = {
1472 OPT__QUIET(&quiet, N_("suppress submodule status output")),
1473 OPT__FORCE(&force, N_("remove submodule working trees even if they contain local changes"), 0),
1474 OPT_BOOL(0, "all", &all, N_("unregister all submodules")),
1475 OPT_END()
1476 };
1477 const char *const git_submodule_helper_usage[] = {
1478 N_("git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"),
1479 NULL
1480 };
1481 int ret = 1;
1482
1483 argc = parse_options(argc, argv, prefix, module_deinit_options,
1484 git_submodule_helper_usage, 0);
1485
1486 if (all && argc) {
1487 error("pathspec and --all are incompatible");
1488 usage_with_options(git_submodule_helper_usage,
1489 module_deinit_options);
1490 }
1491
1492 if (!argc && !all)
1493 die(_("Use '--all' if you really want to deinitialize all submodules"));
1494
1495 if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
1496 goto cleanup;
1497
1498 info.prefix = prefix;
1499 if (quiet)
1500 info.flags |= OPT_QUIET;
1501 if (force)
1502 info.flags |= OPT_FORCE;
1503
1504 for_each_listed_submodule(&list, deinit_submodule_cb, &info);
1505
1506 ret = 0;
1507 cleanup:
1508 module_list_release(&list);
1509 clear_pathspec(&pathspec);
1510 return ret;
1511 }
1512
1513 struct module_clone_data {
1514 const char *prefix;
1515 const char *path;
1516 const char *name;
1517 const char *url;
1518 const char *depth;
1519 struct list_objects_filter_options *filter_options;
1520 unsigned int quiet: 1;
1521 unsigned int progress: 1;
1522 unsigned int dissociate: 1;
1523 unsigned int require_init: 1;
1524 int single_branch;
1525 };
1526 #define MODULE_CLONE_DATA_INIT { \
1527 .single_branch = -1, \
1528 }
1529
1530 struct submodule_alternate_setup {
1531 const char *submodule_name;
1532 enum SUBMODULE_ALTERNATE_ERROR_MODE {
1533 SUBMODULE_ALTERNATE_ERROR_DIE,
1534 SUBMODULE_ALTERNATE_ERROR_INFO,
1535 SUBMODULE_ALTERNATE_ERROR_IGNORE
1536 } error_mode;
1537 struct string_list *reference;
1538 };
1539 #define SUBMODULE_ALTERNATE_SETUP_INIT { \
1540 .error_mode = SUBMODULE_ALTERNATE_ERROR_IGNORE, \
1541 }
1542
1543 static const char alternate_error_advice[] = N_(
1544 "An alternate computed from a superproject's alternate is invalid.\n"
1545 "To allow Git to clone without an alternate in such a case, set\n"
1546 "submodule.alternateErrorStrategy to 'info' or, equivalently, clone with\n"
1547 "'--reference-if-able' instead of '--reference'."
1548 );
1549
1550 static int add_possible_reference_from_superproject(
1551 struct object_directory *odb, void *sas_cb)
1552 {
1553 struct submodule_alternate_setup *sas = sas_cb;
1554 size_t len;
1555
1556 /*
1557 * If the alternate object store is another repository, try the
1558 * standard layout with .git/(modules/<name>)+/objects
1559 */
1560 if (strip_suffix(odb->path, "/objects", &len)) {
1561 struct repository alternate;
1562 char *sm_alternate;
1563 struct strbuf sb = STRBUF_INIT;
1564 struct strbuf err = STRBUF_INIT;
1565 strbuf_add(&sb, odb->path, len);
1566
1567 if (repo_init(&alternate, sb.buf, NULL) < 0)
1568 die(_("could not get a repository handle for gitdir '%s'"),
1569 sb.buf);
1570
1571 /*
1572 * We need to end the new path with '/' to mark it as a dir,
1573 * otherwise a submodule name containing '/' will be broken
1574 * as the last part of a missing submodule reference would
1575 * be taken as a file name.
1576 */
1577 strbuf_reset(&sb);
1578 submodule_name_to_gitdir(&sb, &alternate, sas->submodule_name);
1579 strbuf_addch(&sb, '/');
1580 repo_clear(&alternate);
1581
1582 sm_alternate = compute_alternate_path(sb.buf, &err);
1583 if (sm_alternate) {
1584 char *p = strbuf_detach(&sb, NULL);
1585
1586 string_list_append(sas->reference, p)->util = p;
1587 free(sm_alternate);
1588 } else {
1589 switch (sas->error_mode) {
1590 case SUBMODULE_ALTERNATE_ERROR_DIE:
1591 if (advice_enabled(ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE))
1592 advise(_(alternate_error_advice));
1593 die(_("submodule '%s' cannot add alternate: %s"),
1594 sas->submodule_name, err.buf);
1595 case SUBMODULE_ALTERNATE_ERROR_INFO:
1596 fprintf_ln(stderr, _("submodule '%s' cannot add alternate: %s"),
1597 sas->submodule_name, err.buf);
1598 case SUBMODULE_ALTERNATE_ERROR_IGNORE:
1599 ; /* nothing */
1600 }
1601 }
1602 strbuf_release(&sb);
1603 }
1604
1605 return 0;
1606 }
1607
1608 static void prepare_possible_alternates(const char *sm_name,
1609 struct string_list *reference)
1610 {
1611 char *sm_alternate = NULL, *error_strategy = NULL;
1612 struct submodule_alternate_setup sas = SUBMODULE_ALTERNATE_SETUP_INIT;
1613
1614 git_config_get_string("submodule.alternateLocation", &sm_alternate);
1615 if (!sm_alternate)
1616 return;
1617
1618 git_config_get_string("submodule.alternateErrorStrategy", &error_strategy);
1619
1620 if (!error_strategy)
1621 error_strategy = xstrdup("die");
1622
1623 sas.submodule_name = sm_name;
1624 sas.reference = reference;
1625 if (!strcmp(error_strategy, "die"))
1626 sas.error_mode = SUBMODULE_ALTERNATE_ERROR_DIE;
1627 else if (!strcmp(error_strategy, "info"))
1628 sas.error_mode = SUBMODULE_ALTERNATE_ERROR_INFO;
1629 else if (!strcmp(error_strategy, "ignore"))
1630 sas.error_mode = SUBMODULE_ALTERNATE_ERROR_IGNORE;
1631 else
1632 die(_("Value '%s' for submodule.alternateErrorStrategy is not recognized"), error_strategy);
1633
1634 if (!strcmp(sm_alternate, "superproject"))
1635 foreach_alt_odb(add_possible_reference_from_superproject, &sas);
1636 else if (!strcmp(sm_alternate, "no"))
1637 ; /* do nothing */
1638 else
1639 die(_("Value '%s' for submodule.alternateLocation is not recognized"), sm_alternate);
1640
1641 free(sm_alternate);
1642 free(error_strategy);
1643 }
1644
1645 static char *clone_submodule_sm_gitdir(const char *name)
1646 {
1647 struct strbuf sb = STRBUF_INIT;
1648 char *sm_gitdir;
1649
1650 submodule_name_to_gitdir(&sb, the_repository, name);
1651 sm_gitdir = absolute_pathdup(sb.buf);
1652 strbuf_release(&sb);
1653
1654 return sm_gitdir;
1655 }
1656
1657 static int clone_submodule(const struct module_clone_data *clone_data,
1658 struct string_list *reference)
1659 {
1660 char *p;
1661 char *sm_gitdir = clone_submodule_sm_gitdir(clone_data->name);
1662 char *sm_alternate = NULL, *error_strategy = NULL;
1663 struct child_process cp = CHILD_PROCESS_INIT;
1664 const char *clone_data_path = clone_data->path;
1665 char *to_free = NULL;
1666
1667 if (!is_absolute_path(clone_data->path))
1668 clone_data_path = to_free = xstrfmt("%s/%s", get_git_work_tree(),
1669 clone_data->path);
1670
1671 if (validate_submodule_git_dir(sm_gitdir, clone_data->name) < 0)
1672 die(_("refusing to create/use '%s' in another submodule's "
1673 "git dir"), sm_gitdir);
1674
1675 if (!file_exists(sm_gitdir)) {
1676 if (safe_create_leading_directories_const(sm_gitdir) < 0)
1677 die(_("could not create directory '%s'"), sm_gitdir);
1678
1679 prepare_possible_alternates(clone_data->name, reference);
1680
1681 strvec_push(&cp.args, "clone");
1682 strvec_push(&cp.args, "--no-checkout");
1683 if (clone_data->quiet)
1684 strvec_push(&cp.args, "--quiet");
1685 if (clone_data->progress)
1686 strvec_push(&cp.args, "--progress");
1687 if (clone_data->depth && *(clone_data->depth))
1688 strvec_pushl(&cp.args, "--depth", clone_data->depth, NULL);
1689 if (reference->nr) {
1690 struct string_list_item *item;
1691
1692 for_each_string_list_item(item, reference)
1693 strvec_pushl(&cp.args, "--reference",
1694 item->string, NULL);
1695 }
1696 if (clone_data->dissociate)
1697 strvec_push(&cp.args, "--dissociate");
1698 if (sm_gitdir && *sm_gitdir)
1699 strvec_pushl(&cp.args, "--separate-git-dir", sm_gitdir, NULL);
1700 if (clone_data->filter_options && clone_data->filter_options->choice)
1701 strvec_pushf(&cp.args, "--filter=%s",
1702 expand_list_objects_filter_spec(
1703 clone_data->filter_options));
1704 if (clone_data->single_branch >= 0)
1705 strvec_push(&cp.args, clone_data->single_branch ?
1706 "--single-branch" :
1707 "--no-single-branch");
1708
1709 strvec_push(&cp.args, "--");
1710 strvec_push(&cp.args, clone_data->url);
1711 strvec_push(&cp.args, clone_data_path);
1712
1713 cp.git_cmd = 1;
1714 prepare_submodule_repo_env(&cp.env);
1715 cp.no_stdin = 1;
1716
1717 if(run_command(&cp))
1718 die(_("clone of '%s' into submodule path '%s' failed"),
1719 clone_data->url, clone_data_path);
1720 } else {
1721 char *path;
1722
1723 if (clone_data->require_init && !access(clone_data_path, X_OK) &&
1724 !is_empty_dir(clone_data_path))
1725 die(_("directory not empty: '%s'"), clone_data_path);
1726 if (safe_create_leading_directories_const(clone_data_path) < 0)
1727 die(_("could not create directory '%s'"), clone_data_path);
1728 path = xstrfmt("%s/index", sm_gitdir);
1729 unlink_or_warn(path);
1730 free(path);
1731 }
1732
1733 connect_work_tree_and_git_dir(clone_data_path, sm_gitdir, 0);
1734
1735 p = git_pathdup_submodule(clone_data_path, "config");
1736 if (!p)
1737 die(_("could not get submodule directory for '%s'"), clone_data_path);
1738
1739 /* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */
1740 git_config_get_string("submodule.alternateLocation", &sm_alternate);
1741 if (sm_alternate)
1742 git_config_set_in_file(p, "submodule.alternateLocation",
1743 sm_alternate);
1744 git_config_get_string("submodule.alternateErrorStrategy", &error_strategy);
1745 if (error_strategy)
1746 git_config_set_in_file(p, "submodule.alternateErrorStrategy",
1747 error_strategy);
1748
1749 free(sm_alternate);
1750 free(error_strategy);
1751
1752 free(sm_gitdir);
1753 free(p);
1754 free(to_free);
1755 return 0;
1756 }
1757
1758 static int module_clone(int argc, const char **argv, const char *prefix)
1759 {
1760 int dissociate = 0, quiet = 0, progress = 0, require_init = 0;
1761 struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;
1762 struct string_list reference = STRING_LIST_INIT_NODUP;
1763 struct list_objects_filter_options filter_options =
1764 LIST_OBJECTS_FILTER_INIT;
1765
1766 struct option module_clone_options[] = {
1767 OPT_STRING(0, "prefix", &clone_data.prefix,
1768 N_("path"),
1769 N_("alternative anchor for relative paths")),
1770 OPT_STRING(0, "path", &clone_data.path,
1771 N_("path"),
1772 N_("where the new submodule will be cloned to")),
1773 OPT_STRING(0, "name", &clone_data.name,
1774 N_("string"),
1775 N_("name of the new submodule")),
1776 OPT_STRING(0, "url", &clone_data.url,
1777 N_("string"),
1778 N_("url where to clone the submodule from")),
1779 OPT_STRING_LIST(0, "reference", &reference,
1780 N_("repo"),
1781 N_("reference repository")),
1782 OPT_BOOL(0, "dissociate", &dissociate,
1783 N_("use --reference only while cloning")),
1784 OPT_STRING(0, "depth", &clone_data.depth,
1785 N_("string"),
1786 N_("depth for shallow clones")),
1787 OPT__QUIET(&quiet, "suppress output for cloning a submodule"),
1788 OPT_BOOL(0, "progress", &progress,
1789 N_("force cloning progress")),
1790 OPT_BOOL(0, "require-init", &require_init,
1791 N_("disallow cloning into non-empty directory")),
1792 OPT_BOOL(0, "single-branch", &clone_data.single_branch,
1793 N_("clone only one branch, HEAD or --branch")),
1794 OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
1795 OPT_END()
1796 };
1797 const char *const git_submodule_helper_usage[] = {
1798 N_("git submodule--helper clone [--prefix=<path>] [--quiet] "
1799 "[--reference <repository>] [--name <name>] [--depth <depth>] "
1800 "[--single-branch] [--filter <filter-spec>] "
1801 "--url <url> --path <path>"),
1802 NULL
1803 };
1804
1805 argc = parse_options(argc, argv, prefix, module_clone_options,
1806 git_submodule_helper_usage, 0);
1807
1808 clone_data.dissociate = !!dissociate;
1809 clone_data.quiet = !!quiet;
1810 clone_data.progress = !!progress;
1811 clone_data.require_init = !!require_init;
1812 clone_data.filter_options = &filter_options;
1813
1814 if (argc || !clone_data.url || !clone_data.path || !*(clone_data.path))
1815 usage_with_options(git_submodule_helper_usage,
1816 module_clone_options);
1817
1818 clone_submodule(&clone_data, &reference);
1819 list_objects_filter_release(&filter_options);
1820 string_list_clear(&reference, 1);
1821 return 0;
1822 }
1823
1824 static int determine_submodule_update_strategy(struct repository *r,
1825 int just_cloned,
1826 const char *path,
1827 enum submodule_update_type update,
1828 struct submodule_update_strategy *out)
1829 {
1830 const struct submodule *sub = submodule_from_path(r, null_oid(), path);
1831 char *key;
1832 const char *val;
1833 int ret;
1834
1835 key = xstrfmt("submodule.%s.update", sub->name);
1836
1837 if (update) {
1838 out->type = update;
1839 } else if (!repo_config_get_string_tmp(r, key, &val)) {
1840 if (parse_submodule_update_strategy(val, out) < 0) {
1841 ret = die_message(_("Invalid update mode '%s' configured for submodule path '%s'"),
1842 val, path);
1843 goto cleanup;
1844 }
1845 } else if (sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
1846 if (sub->update_strategy.type == SM_UPDATE_COMMAND)
1847 BUG("how did we read update = !command from .gitmodules?");
1848 out->type = sub->update_strategy.type;
1849 out->command = sub->update_strategy.command;
1850 } else
1851 out->type = SM_UPDATE_CHECKOUT;
1852
1853 if (just_cloned &&
1854 (out->type == SM_UPDATE_MERGE ||
1855 out->type == SM_UPDATE_REBASE ||
1856 out->type == SM_UPDATE_NONE))
1857 out->type = SM_UPDATE_CHECKOUT;
1858
1859 ret = 0;
1860 cleanup:
1861 free(key);
1862 return ret;
1863 }
1864
1865 struct update_clone_data {
1866 const struct submodule *sub;
1867 struct object_id oid;
1868 unsigned just_cloned;
1869 };
1870
1871 struct submodule_update_clone {
1872 /* index into 'update_data.list', the list of submodules to look into for cloning */
1873 int current;
1874
1875 /* configuration parameters which are passed on to the children */
1876 const struct update_data *update_data;
1877
1878 /* to be consumed by update_submodule() */
1879 struct update_clone_data *update_clone;
1880 int update_clone_nr; int update_clone_alloc;
1881
1882 /* If we want to stop as fast as possible and return an error */
1883 unsigned quickstop : 1;
1884
1885 /* failed clones to be retried again */
1886 const struct cache_entry **failed_clones;
1887 int failed_clones_nr, failed_clones_alloc;
1888 };
1889 #define SUBMODULE_UPDATE_CLONE_INIT { 0 }
1890
1891 static void submodule_update_clone_release(struct submodule_update_clone *suc)
1892 {
1893 free(suc->update_clone);
1894 free(suc->failed_clones);
1895 }
1896
1897 struct update_data {
1898 const char *prefix;
1899 const char *super_prefix;
1900 char *displaypath;
1901 enum submodule_update_type update_default;
1902 struct object_id suboid;
1903 struct string_list references;
1904 struct submodule_update_strategy update_strategy;
1905 struct list_objects_filter_options *filter_options;
1906 struct module_list list;
1907 int depth;
1908 int max_jobs;
1909 int single_branch;
1910 int recommend_shallow;
1911 unsigned int require_init;
1912 unsigned int force;
1913 unsigned int quiet;
1914 unsigned int nofetch;
1915 unsigned int remote;
1916 unsigned int progress;
1917 unsigned int dissociate;
1918 unsigned int init;
1919 unsigned int warn_if_uninitialized;
1920 unsigned int recursive;
1921
1922 /* copied over from update_clone_data */
1923 struct object_id oid;
1924 unsigned int just_cloned;
1925 const char *sm_path;
1926 };
1927 #define UPDATE_DATA_INIT { \
1928 .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \
1929 .list = MODULE_LIST_INIT, \
1930 .recommend_shallow = -1, \
1931 .references = STRING_LIST_INIT_DUP, \
1932 .single_branch = -1, \
1933 .max_jobs = 1, \
1934 }
1935
1936 static void update_data_release(struct update_data *ud)
1937 {
1938 free(ud->displaypath);
1939 module_list_release(&ud->list);
1940 }
1941
1942 static void next_submodule_warn_missing(struct submodule_update_clone *suc,
1943 struct strbuf *out, const char *displaypath)
1944 {
1945 /*
1946 * Only mention uninitialized submodules when their
1947 * paths have been specified.
1948 */
1949 if (suc->update_data->warn_if_uninitialized) {
1950 strbuf_addf(out,
1951 _("Submodule path '%s' not initialized"),
1952 displaypath);
1953 strbuf_addch(out, '\n');
1954 strbuf_addstr(out,
1955 _("Maybe you want to use 'update --init'?"));
1956 strbuf_addch(out, '\n');
1957 }
1958 }
1959
1960 /**
1961 * Determine whether 'ce' needs to be cloned. If so, prepare the 'child' to
1962 * run the clone. Returns 1 if 'ce' needs to be cloned, 0 otherwise.
1963 */
1964 static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
1965 struct child_process *child,
1966 struct submodule_update_clone *suc,
1967 struct strbuf *out)
1968 {
1969 const struct submodule *sub = NULL;
1970 const char *url = NULL;
1971 const char *update_string;
1972 enum submodule_update_type update_type;
1973 char *key;
1974 const struct update_data *ud = suc->update_data;
1975 char *displaypath = get_submodule_displaypath(ce->name, ud->prefix,
1976 ud->super_prefix);
1977 struct strbuf sb = STRBUF_INIT;
1978 int needs_cloning = 0;
1979 int need_free_url = 0;
1980
1981 if (ce_stage(ce)) {
1982 strbuf_addf(out, _("Skipping unmerged submodule %s"), displaypath);
1983 strbuf_addch(out, '\n');
1984 goto cleanup;
1985 }
1986
1987 sub = submodule_from_path(the_repository, null_oid(), ce->name);
1988
1989 if (!sub) {
1990 next_submodule_warn_missing(suc, out, displaypath);
1991 goto cleanup;
1992 }
1993
1994 key = xstrfmt("submodule.%s.update", sub->name);
1995 if (!repo_config_get_string_tmp(the_repository, key, &update_string)) {
1996 update_type = parse_submodule_update_type(update_string);
1997 } else {
1998 update_type = sub->update_strategy.type;
1999 }
2000 free(key);
2001
2002 if (suc->update_data->update_strategy.type == SM_UPDATE_NONE
2003 || (suc->update_data->update_strategy.type == SM_UPDATE_UNSPECIFIED
2004 && update_type == SM_UPDATE_NONE)) {
2005 strbuf_addf(out, _("Skipping submodule '%s'"), displaypath);
2006 strbuf_addch(out, '\n');
2007 goto cleanup;
2008 }
2009
2010 /* Check if the submodule has been initialized. */
2011 if (!is_submodule_active(the_repository, ce->name)) {
2012 next_submodule_warn_missing(suc, out, displaypath);
2013 goto cleanup;
2014 }
2015
2016 strbuf_reset(&sb);
2017 strbuf_addf(&sb, "submodule.%s.url", sub->name);
2018 if (repo_config_get_string_tmp(the_repository, sb.buf, &url)) {
2019 if (starts_with_dot_slash(sub->url) ||
2020 starts_with_dot_dot_slash(sub->url)) {
2021 url = resolve_relative_url(sub->url, NULL, 0);
2022 need_free_url = 1;
2023 } else
2024 url = sub->url;
2025 }
2026
2027 strbuf_reset(&sb);
2028 strbuf_addf(&sb, "%s/.git", ce->name);
2029 needs_cloning = !file_exists(sb.buf);
2030
2031 ALLOC_GROW(suc->update_clone, suc->update_clone_nr + 1,
2032 suc->update_clone_alloc);
2033 oidcpy(&suc->update_clone[suc->update_clone_nr].oid, &ce->oid);
2034 suc->update_clone[suc->update_clone_nr].just_cloned = needs_cloning;
2035 suc->update_clone[suc->update_clone_nr].sub = sub;
2036 suc->update_clone_nr++;
2037
2038 if (!needs_cloning)
2039 goto cleanup;
2040
2041 child->git_cmd = 1;
2042 child->no_stdin = 1;
2043 child->stdout_to_stderr = 1;
2044 child->err = -1;
2045 strvec_push(&child->args, "submodule--helper");
2046 strvec_push(&child->args, "clone");
2047 if (suc->update_data->progress)
2048 strvec_push(&child->args, "--progress");
2049 if (suc->update_data->quiet)
2050 strvec_push(&child->args, "--quiet");
2051 if (suc->update_data->prefix)
2052 strvec_pushl(&child->args, "--prefix", suc->update_data->prefix, NULL);
2053 if (suc->update_data->recommend_shallow && sub->recommend_shallow == 1)
2054 strvec_push(&child->args, "--depth=1");
2055 else if (suc->update_data->depth)
2056 strvec_pushf(&child->args, "--depth=%d", suc->update_data->depth);
2057 if (suc->update_data->filter_options && suc->update_data->filter_options->choice)
2058 strvec_pushf(&child->args, "--filter=%s",
2059 expand_list_objects_filter_spec(suc->update_data->filter_options));
2060 if (suc->update_data->require_init)
2061 strvec_push(&child->args, "--require-init");
2062 strvec_pushl(&child->args, "--path", sub->path, NULL);
2063 strvec_pushl(&child->args, "--name", sub->name, NULL);
2064 strvec_pushl(&child->args, "--url", url, NULL);
2065 if (suc->update_data->references.nr) {
2066 struct string_list_item *item;
2067
2068 for_each_string_list_item(item, &suc->update_data->references)
2069 strvec_pushl(&child->args, "--reference", item->string, NULL);
2070 }
2071 if (suc->update_data->dissociate)
2072 strvec_push(&child->args, "--dissociate");
2073 if (suc->update_data->single_branch >= 0)
2074 strvec_push(&child->args, suc->update_data->single_branch ?
2075 "--single-branch" :
2076 "--no-single-branch");
2077
2078 cleanup:
2079 free(displaypath);
2080 strbuf_release(&sb);
2081 if (need_free_url)
2082 free((void*)url);
2083
2084 return needs_cloning;
2085 }
2086
2087 static int update_clone_get_next_task(struct child_process *child,
2088 struct strbuf *err,
2089 void *suc_cb,
2090 void **idx_task_cb)
2091 {
2092 struct submodule_update_clone *suc = suc_cb;
2093 const struct cache_entry *ce;
2094 int index;
2095
2096 for (; suc->current < suc->update_data->list.nr; suc->current++) {
2097 ce = suc->update_data->list.entries[suc->current];
2098 if (prepare_to_clone_next_submodule(ce, child, suc, err)) {
2099 int *p = xmalloc(sizeof(*p));
2100
2101 *p = suc->current;
2102 *idx_task_cb = p;
2103 suc->current++;
2104 return 1;
2105 }
2106 }
2107
2108 /*
2109 * The loop above tried cloning each submodule once, now try the
2110 * stragglers again, which we can imagine as an extension of the
2111 * entry list.
2112 */
2113 index = suc->current - suc->update_data->list.nr;
2114 if (index < suc->failed_clones_nr) {
2115 int *p;
2116
2117 ce = suc->failed_clones[index];
2118 if (!prepare_to_clone_next_submodule(ce, child, suc, err)) {
2119 suc->current ++;
2120 strbuf_addstr(err, "BUG: submodule considered for "
2121 "cloning, doesn't need cloning "
2122 "any more?\n");
2123 return 0;
2124 }
2125 p = xmalloc(sizeof(*p));
2126 *p = suc->current;
2127 *idx_task_cb = p;
2128 suc->current ++;
2129 return 1;
2130 }
2131
2132 return 0;
2133 }
2134
2135 static int update_clone_start_failure(struct strbuf *err,
2136 void *suc_cb,
2137 void *idx_task_cb)
2138 {
2139 struct submodule_update_clone *suc = suc_cb;
2140
2141 suc->quickstop = 1;
2142 return 1;
2143 }
2144
2145 static int update_clone_task_finished(int result,
2146 struct strbuf *err,
2147 void *suc_cb,
2148 void *idx_task_cb)
2149 {
2150 const struct cache_entry *ce;
2151 struct submodule_update_clone *suc = suc_cb;
2152 int *idxP = idx_task_cb;
2153 int idx = *idxP;
2154
2155 free(idxP);
2156
2157 if (!result)
2158 return 0;
2159
2160 if (idx < suc->update_data->list.nr) {
2161 ce = suc->update_data->list.entries[idx];
2162 strbuf_addf(err, _("Failed to clone '%s'. Retry scheduled"),
2163 ce->name);
2164 strbuf_addch(err, '\n');
2165 ALLOC_GROW(suc->failed_clones,
2166 suc->failed_clones_nr + 1,
2167 suc->failed_clones_alloc);
2168 suc->failed_clones[suc->failed_clones_nr++] = ce;
2169 return 0;
2170 } else {
2171 idx -= suc->update_data->list.nr;
2172 ce = suc->failed_clones[idx];
2173 strbuf_addf(err, _("Failed to clone '%s' a second time, aborting"),
2174 ce->name);
2175 strbuf_addch(err, '\n');
2176 suc->quickstop = 1;
2177 return 1;
2178 }
2179
2180 return 0;
2181 }
2182
2183 static int git_update_clone_config(const char *var, const char *value,
2184 void *cb)
2185 {
2186 int *max_jobs = cb;
2187
2188 if (!strcmp(var, "submodule.fetchjobs"))
2189 *max_jobs = parse_submodule_fetchjobs(var, value);
2190 return 0;
2191 }
2192
2193 static int is_tip_reachable(const char *path, const struct object_id *oid)
2194 {
2195 struct child_process cp = CHILD_PROCESS_INIT;
2196 struct strbuf rev = STRBUF_INIT;
2197 char *hex = oid_to_hex(oid);
2198
2199 cp.git_cmd = 1;
2200 cp.dir = path;
2201 cp.no_stderr = 1;
2202 strvec_pushl(&cp.args, "rev-list", "-n", "1", hex, "--not", "--all", NULL);
2203
2204 prepare_submodule_repo_env(&cp.env);
2205
2206 if (capture_command(&cp, &rev, GIT_MAX_HEXSZ + 1) || rev.len)
2207 return 0;
2208
2209 return 1;
2210 }
2211
2212 static int fetch_in_submodule(const char *module_path, int depth, int quiet,
2213 const struct object_id *oid)
2214 {
2215 struct child_process cp = CHILD_PROCESS_INIT;
2216
2217 prepare_submodule_repo_env(&cp.env);
2218 cp.git_cmd = 1;
2219 cp.dir = module_path;
2220
2221 strvec_push(&cp.args, "fetch");
2222 if (quiet)
2223 strvec_push(&cp.args, "--quiet");
2224 if (depth)
2225 strvec_pushf(&cp.args, "--depth=%d", depth);
2226 if (oid) {
2227 char *hex = oid_to_hex(oid);
2228 char *remote = get_default_remote();
2229
2230 strvec_pushl(&cp.args, remote, hex, NULL);
2231 free(remote);
2232 }
2233
2234 return run_command(&cp);
2235 }
2236
2237 static int run_update_command(const struct update_data *ud, int subforce)
2238 {
2239 struct child_process cp = CHILD_PROCESS_INIT;
2240 char *oid = oid_to_hex(&ud->oid);
2241 int ret;
2242
2243 switch (ud->update_strategy.type) {
2244 case SM_UPDATE_CHECKOUT:
2245 cp.git_cmd = 1;
2246 strvec_pushl(&cp.args, "checkout", "-q", NULL);
2247 if (subforce)
2248 strvec_push(&cp.args, "-f");
2249 break;
2250 case SM_UPDATE_REBASE:
2251 cp.git_cmd = 1;
2252 strvec_push(&cp.args, "rebase");
2253 if (ud->quiet)
2254 strvec_push(&cp.args, "--quiet");
2255 break;
2256 case SM_UPDATE_MERGE:
2257 cp.git_cmd = 1;
2258 strvec_push(&cp.args, "merge");
2259 if (ud->quiet)
2260 strvec_push(&cp.args, "--quiet");
2261 break;
2262 case SM_UPDATE_COMMAND:
2263 cp.use_shell = 1;
2264 strvec_push(&cp.args, ud->update_strategy.command);
2265 break;
2266 default:
2267 BUG("unexpected update strategy type: %d",
2268 ud->update_strategy.type);
2269 }
2270 strvec_push(&cp.args, oid);
2271
2272 cp.dir = ud->sm_path;
2273 prepare_submodule_repo_env(&cp.env);
2274 if ((ret = run_command(&cp))) {
2275 switch (ud->update_strategy.type) {
2276 case SM_UPDATE_CHECKOUT:
2277 die_message(_("Unable to checkout '%s' in submodule path '%s'"),
2278 oid, ud->displaypath);
2279 /* No "ret" assignment, use "git checkout"'s */
2280 break;
2281 case SM_UPDATE_REBASE:
2282 ret = die_message(_("Unable to rebase '%s' in submodule path '%s'"),
2283 oid, ud->displaypath);
2284 break;
2285 case SM_UPDATE_MERGE:
2286 ret = die_message(_("Unable to merge '%s' in submodule path '%s'"),
2287 oid, ud->displaypath);
2288 break;
2289 case SM_UPDATE_COMMAND:
2290 ret = die_message(_("Execution of '%s %s' failed in submodule path '%s'"),
2291 ud->update_strategy.command, oid, ud->displaypath);
2292 break;
2293 default:
2294 BUG("unexpected update strategy type: %d",
2295 ud->update_strategy.type);
2296 }
2297
2298 return ret;
2299 }
2300
2301 if (ud->quiet)
2302 return 0;
2303
2304 switch (ud->update_strategy.type) {
2305 case SM_UPDATE_CHECKOUT:
2306 printf(_("Submodule path '%s': checked out '%s'\n"),
2307 ud->displaypath, oid);
2308 break;
2309 case SM_UPDATE_REBASE:
2310 printf(_("Submodule path '%s': rebased into '%s'\n"),
2311 ud->displaypath, oid);
2312 break;
2313 case SM_UPDATE_MERGE:
2314 printf(_("Submodule path '%s': merged in '%s'\n"),
2315 ud->displaypath, oid);
2316 break;
2317 case SM_UPDATE_COMMAND:
2318 printf(_("Submodule path '%s': '%s %s'\n"),
2319 ud->displaypath, ud->update_strategy.command, oid);
2320 break;
2321 default:
2322 BUG("unexpected update strategy type: %d",
2323 ud->update_strategy.type);
2324 }
2325
2326 return 0;
2327 }
2328
2329 static int run_update_procedure(const struct update_data *ud)
2330 {
2331 int subforce = is_null_oid(&ud->suboid) || ud->force;
2332
2333 if (!ud->nofetch) {
2334 /*
2335 * Run fetch only if `oid` isn't present or it
2336 * is not reachable from a ref.
2337 */
2338 if (!is_tip_reachable(ud->sm_path, &ud->oid) &&
2339 fetch_in_submodule(ud->sm_path, ud->depth, ud->quiet, NULL) &&
2340 !ud->quiet)
2341 fprintf_ln(stderr,
2342 _("Unable to fetch in submodule path '%s'; "
2343 "trying to directly fetch %s:"),
2344 ud->displaypath, oid_to_hex(&ud->oid));
2345 /*
2346 * Now we tried the usual fetch, but `oid` may
2347 * not be reachable from any of the refs.
2348 */
2349 if (!is_tip_reachable(ud->sm_path, &ud->oid) &&
2350 fetch_in_submodule(ud->sm_path, ud->depth, ud->quiet, &ud->oid))
2351 return die_message(_("Fetched in submodule path '%s', but it did not "
2352 "contain %s. Direct fetching of that commit failed."),
2353 ud->displaypath, oid_to_hex(&ud->oid));
2354 }
2355
2356 return run_update_command(ud, subforce);
2357 }
2358
2359 static int remote_submodule_branch(const char *path, const char **branch)
2360 {
2361 const struct submodule *sub;
2362 char *key;
2363 *branch = NULL;
2364
2365 sub = submodule_from_path(the_repository, null_oid(), path);
2366 if (!sub)
2367 return die_message(_("could not initialize submodule at path '%s'"),
2368 path);
2369
2370 key = xstrfmt("submodule.%s.branch", sub->name);
2371 if (repo_config_get_string_tmp(the_repository, key, branch))
2372 *branch = sub->branch;
2373 free(key);
2374
2375 if (!*branch) {
2376 *branch = "HEAD";
2377 return 0;
2378 }
2379
2380 if (!strcmp(*branch, ".")) {
2381 const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
2382
2383 if (!refname)
2384 return die_message(_("No such ref: %s"), "HEAD");
2385
2386 /* detached HEAD */
2387 if (!strcmp(refname, "HEAD"))
2388 return die_message(_("Submodule (%s) branch configured to inherit "
2389 "branch from superproject, but the superproject "
2390 "is not on any branch"), sub->name);
2391
2392 if (!skip_prefix(refname, "refs/heads/", &refname))
2393 return die_message(_("Expecting a full ref name, got %s"),
2394 refname);
2395
2396 *branch = refname;
2397 return 0;
2398 }
2399
2400 /* Our "branch" is coming from repo_config_get_string_tmp() */
2401 return 0;
2402 }
2403
2404 static int ensure_core_worktree(const char *path)
2405 {
2406 const char *cw;
2407 struct repository subrepo;
2408
2409 if (repo_submodule_init(&subrepo, the_repository, path, null_oid()))
2410 return die_message(_("could not get a repository handle for submodule '%s'"),
2411 path);
2412
2413 if (!repo_config_get_string_tmp(&subrepo, "core.worktree", &cw)) {
2414 char *cfg_file, *abs_path;
2415 const char *rel_path;
2416 struct strbuf sb = STRBUF_INIT;
2417
2418 cfg_file = repo_git_path(&subrepo, "config");
2419
2420 abs_path = absolute_pathdup(path);
2421 rel_path = relative_path(abs_path, subrepo.gitdir, &sb);
2422
2423 git_config_set_in_file(cfg_file, "core.worktree", rel_path);
2424
2425 free(cfg_file);
2426 free(abs_path);
2427 strbuf_release(&sb);
2428 }
2429
2430 repo_clear(&subrepo);
2431 return 0;
2432 }
2433
2434 static const char *submodule_update_type_to_label(enum submodule_update_type type)
2435 {
2436 switch (type) {
2437 case SM_UPDATE_CHECKOUT:
2438 return "checkout";
2439 case SM_UPDATE_MERGE:
2440 return "merge";
2441 case SM_UPDATE_REBASE:
2442 return "rebase";
2443 case SM_UPDATE_UNSPECIFIED:
2444 case SM_UPDATE_NONE:
2445 case SM_UPDATE_COMMAND:
2446 break;
2447 }
2448 BUG("unreachable with type %d", type);
2449 }
2450
2451 static void update_data_to_args(const struct update_data *update_data,
2452 struct strvec *args)
2453 {
2454 enum submodule_update_type update_type = update_data->update_default;
2455
2456 strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
2457 if (update_data->displaypath) {
2458 strvec_push(args, "--super-prefix");
2459 strvec_pushf(args, "%s/", update_data->displaypath);
2460 }
2461 strvec_pushf(args, "--jobs=%d", update_data->max_jobs);
2462 if (update_data->quiet)
2463 strvec_push(args, "--quiet");
2464 if (update_data->force)
2465 strvec_push(args, "--force");
2466 if (update_data->init)
2467 strvec_push(args, "--init");
2468 if (update_data->remote)
2469 strvec_push(args, "--remote");
2470 if (update_data->nofetch)
2471 strvec_push(args, "--no-fetch");
2472 if (update_data->dissociate)
2473 strvec_push(args, "--dissociate");
2474 if (update_data->progress)
2475 strvec_push(args, "--progress");
2476 if (update_data->require_init)
2477 strvec_push(args, "--require-init");
2478 if (update_data->depth)
2479 strvec_pushf(args, "--depth=%d", update_data->depth);
2480 if (update_type != SM_UPDATE_UNSPECIFIED)
2481 strvec_pushf(args, "--%s",
2482 submodule_update_type_to_label(update_type));
2483
2484 if (update_data->references.nr) {
2485 struct string_list_item *item;
2486
2487 for_each_string_list_item(item, &update_data->references)
2488 strvec_pushl(args, "--reference", item->string, NULL);
2489 }
2490 if (update_data->filter_options && update_data->filter_options->choice)
2491 strvec_pushf(args, "--filter=%s",
2492 expand_list_objects_filter_spec(
2493 update_data->filter_options));
2494 if (update_data->recommend_shallow == 0)
2495 strvec_push(args, "--no-recommend-shallow");
2496 else if (update_data->recommend_shallow == 1)
2497 strvec_push(args, "--recommend-shallow");
2498 if (update_data->single_branch >= 0)
2499 strvec_push(args, update_data->single_branch ?
2500 "--single-branch" :
2501 "--no-single-branch");
2502 }
2503
2504 static int update_submodule(struct update_data *update_data)
2505 {
2506 int ret;
2507
2508 ret = determine_submodule_update_strategy(the_repository,
2509 update_data->just_cloned,
2510 update_data->sm_path,
2511 update_data->update_default,
2512 &update_data->update_strategy);
2513 if (ret)
2514 return ret;
2515
2516 if (update_data->just_cloned)
2517 oidcpy(&update_data->suboid, null_oid());
2518 else if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid))
2519 return die_message(_("Unable to find current revision in submodule path '%s'"),
2520 update_data->displaypath);
2521
2522 if (update_data->remote) {
2523 char *remote_name;
2524 const char *branch;
2525 char *remote_ref;
2526 int code;
2527
2528 code = get_default_remote_submodule(update_data->sm_path, &remote_name);
2529 if (code)
2530 return code;
2531 code = remote_submodule_branch(update_data->sm_path, &branch);
2532 if (code)
2533 return code;
2534 remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch);
2535
2536 free(remote_name);
2537
2538 if (!update_data->nofetch) {
2539 if (fetch_in_submodule(update_data->sm_path, update_data->depth,
2540 0, NULL))
2541 return die_message(_("Unable to fetch in submodule path '%s'"),
2542 update_data->sm_path);
2543 }
2544
2545 if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid))
2546 return die_message(_("Unable to find %s revision in submodule path '%s'"),
2547 remote_ref, update_data->sm_path);
2548
2549 free(remote_ref);
2550 }
2551
2552 if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) {
2553 ret = run_update_procedure(update_data);
2554 if (ret)
2555 return ret;
2556 }
2557
2558 if (update_data->recursive) {
2559 struct child_process cp = CHILD_PROCESS_INIT;
2560 struct update_data next = *update_data;
2561
2562 next.prefix = NULL;
2563 oidcpy(&next.oid, null_oid());
2564 oidcpy(&next.suboid, null_oid());
2565
2566 cp.dir = update_data->sm_path;
2567 cp.git_cmd = 1;
2568 prepare_submodule_repo_env(&cp.env);
2569 update_data_to_args(&next, &cp.args);
2570
2571 ret = run_command(&cp);
2572 if (ret)
2573 die_message(_("Failed to recurse into submodule path '%s'"),
2574 update_data->displaypath);
2575 return ret;
2576 }
2577
2578 return 0;
2579 }
2580
2581 static int update_submodules(struct update_data *update_data)
2582 {
2583 int i, ret = 0;
2584 struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT;
2585 const struct run_process_parallel_opts opts = {
2586 .tr2_category = "submodule",
2587 .tr2_label = "parallel/update",
2588
2589 .processes = update_data->max_jobs,
2590
2591 .get_next_task = update_clone_get_next_task,
2592 .start_failure = update_clone_start_failure,
2593 .task_finished = update_clone_task_finished,
2594 .data = &suc,
2595 };
2596
2597 suc.update_data = update_data;
2598 run_processes_parallel(&opts);
2599
2600 /*
2601 * We saved the output and put it out all at once now.
2602 * That means:
2603 * - the listener does not have to interleave their (checkout)
2604 * work with our fetching. The writes involved in a
2605 * checkout involve more straightforward sequential I/O.
2606 * - the listener can avoid doing any work if fetching failed.
2607 */
2608 if (suc.quickstop) {
2609 ret = 1;
2610 goto cleanup;
2611 }
2612
2613 for (i = 0; i < suc.update_clone_nr; i++) {
2614 struct update_clone_data ucd = suc.update_clone[i];
2615 int code;
2616
2617 oidcpy(&update_data->oid, &ucd.oid);
2618 update_data->just_cloned = ucd.just_cloned;
2619 update_data->sm_path = ucd.sub->path;
2620
2621 code = ensure_core_worktree(update_data->sm_path);
2622 if (code)
2623 goto fail;
2624
2625 update_data->displaypath = get_submodule_displaypath(
2626 update_data->sm_path, update_data->prefix,
2627 update_data->super_prefix);
2628 code = update_submodule(update_data);
2629 FREE_AND_NULL(update_data->displaypath);
2630 fail:
2631 if (!code)
2632 continue;
2633 ret = code;
2634 if (ret == 128)
2635 goto cleanup;
2636 }
2637
2638 cleanup:
2639 submodule_update_clone_release(&suc);
2640 string_list_clear(&update_data->references, 0);
2641 return ret;
2642 }
2643
2644 static int module_update(int argc, const char **argv, const char *prefix)
2645 {
2646 struct pathspec pathspec = { 0 };
2647 struct pathspec pathspec2 = { 0 };
2648 struct update_data opt = UPDATE_DATA_INIT;
2649 struct list_objects_filter_options filter_options =
2650 LIST_OBJECTS_FILTER_INIT;
2651 int ret;
2652 struct option module_update_options[] = {
2653 OPT__SUPER_PREFIX(&opt.super_prefix),
2654 OPT__FORCE(&opt.force, N_("force checkout updates"), 0),
2655 OPT_BOOL(0, "init", &opt.init,
2656 N_("initialize uninitialized submodules before update")),
2657 OPT_BOOL(0, "remote", &opt.remote,
2658 N_("use SHA-1 of submodule's remote tracking branch")),
2659 OPT_BOOL(0, "recursive", &opt.recursive,
2660 N_("traverse submodules recursively")),
2661 OPT_BOOL('N', "no-fetch", &opt.nofetch,
2662 N_("don't fetch new objects from the remote site")),
2663 OPT_SET_INT(0, "checkout", &opt.update_default,
2664 N_("use the 'checkout' update strategy (default)"),
2665 SM_UPDATE_CHECKOUT),
2666 OPT_SET_INT('m', "merge", &opt.update_default,
2667 N_("use the 'merge' update strategy"),
2668 SM_UPDATE_MERGE),
2669 OPT_SET_INT('r', "rebase", &opt.update_default,
2670 N_("use the 'rebase' update strategy"),
2671 SM_UPDATE_REBASE),
2672 OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"),
2673 N_("reference repository")),
2674 OPT_BOOL(0, "dissociate", &opt.dissociate,
2675 N_("use --reference only while cloning")),
2676 OPT_INTEGER(0, "depth", &opt.depth,
2677 N_("create a shallow clone truncated to the "
2678 "specified number of revisions")),
2679 OPT_INTEGER('j', "jobs", &opt.max_jobs,
2680 N_("parallel jobs")),
2681 OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow,
2682 N_("whether the initial clone should follow the shallow recommendation")),
2683 OPT__QUIET(&opt.quiet, N_("don't print cloning progress")),
2684 OPT_BOOL(0, "progress", &opt.progress,
2685 N_("force cloning progress")),
2686 OPT_BOOL(0, "require-init", &opt.require_init,
2687 N_("disallow cloning into non-empty directory, implies --init")),
2688 OPT_BOOL(0, "single-branch", &opt.single_branch,
2689 N_("clone only one branch, HEAD or --branch")),
2690 OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
2691 OPT_END()
2692 };
2693 const char *const git_submodule_helper_usage[] = {
2694 N_("git submodule [--quiet] update"
2695 " [--init [--filter=<filter-spec>]] [--remote]"
2696 " [-N|--no-fetch] [-f|--force]"
2697 " [--checkout|--merge|--rebase]"
2698 " [--[no-]recommend-shallow] [--reference <repository>]"
2699 " [--recursive] [--[no-]single-branch] [--] [<path>...]"),
2700 NULL
2701 };
2702
2703 update_clone_config_from_gitmodules(&opt.max_jobs);
2704 git_config(git_update_clone_config, &opt.max_jobs);
2705
2706 argc = parse_options(argc, argv, prefix, module_update_options,
2707 git_submodule_helper_usage, 0);
2708
2709 if (opt.require_init)
2710 opt.init = 1;
2711
2712 if (filter_options.choice && !opt.init) {
2713 usage_with_options(git_submodule_helper_usage,
2714 module_update_options);
2715 }
2716
2717 opt.filter_options = &filter_options;
2718 opt.prefix = prefix;
2719
2720 if (opt.update_default)
2721 opt.update_strategy.type = opt.update_default;
2722
2723 if (module_list_compute(argv, prefix, &pathspec, &opt.list) < 0) {
2724 ret = 1;
2725 goto cleanup;
2726 }
2727
2728 if (pathspec.nr)
2729 opt.warn_if_uninitialized = 1;
2730
2731 if (opt.init) {
2732 struct module_list list = MODULE_LIST_INIT;
2733 struct init_cb info = INIT_CB_INIT;
2734
2735 if (module_list_compute(argv, opt.prefix,
2736 &pathspec2, &list) < 0) {
2737 module_list_release(&list);
2738 ret = 1;
2739 goto cleanup;
2740 }
2741
2742 /*
2743 * If there are no path args and submodule.active is set then,
2744 * by default, only initialize 'active' modules.
2745 */
2746 if (!argc && git_config_get_value_multi("submodule.active"))
2747 module_list_active(&list);
2748
2749 info.prefix = opt.prefix;
2750 info.super_prefix = opt.super_prefix;
2751 if (opt.quiet)
2752 info.flags |= OPT_QUIET;
2753
2754 for_each_listed_submodule(&list, init_submodule_cb, &info);
2755 module_list_release(&list);
2756 }
2757
2758 ret = update_submodules(&opt);
2759 cleanup:
2760 update_data_release(&opt);
2761 list_objects_filter_release(&filter_options);
2762 clear_pathspec(&pathspec);
2763 clear_pathspec(&pathspec2);
2764 return ret;
2765 }
2766
2767 static int push_check(int argc, const char **argv, const char *prefix)
2768 {
2769 struct remote *remote;
2770 const char *superproject_head;
2771 char *head;
2772 int detached_head = 0;
2773 struct object_id head_oid;
2774
2775 if (argc < 3)
2776 die("submodule--helper push-check requires at least 2 arguments");
2777
2778 /*
2779 * superproject's resolved head ref.
2780 * if HEAD then the superproject is in a detached head state, otherwise
2781 * it will be the resolved head ref.
2782 */
2783 superproject_head = argv[1];
2784 argv++;
2785 argc--;
2786 /* Get the submodule's head ref and determine if it is detached */
2787 head = resolve_refdup("HEAD", 0, &head_oid, NULL);
2788 if (!head)
2789 die(_("Failed to resolve HEAD as a valid ref."));
2790 if (!strcmp(head, "HEAD"))
2791 detached_head = 1;
2792
2793 /*
2794 * The remote must be configured.
2795 * This is to avoid pushing to the exact same URL as the parent.
2796 */
2797 remote = pushremote_get(argv[1]);
2798 if (!remote || remote->origin == REMOTE_UNCONFIGURED)
2799 die("remote '%s' not configured", argv[1]);
2800
2801 /* Check the refspec */
2802 if (argc > 2) {
2803 int i;
2804 struct ref *local_refs = get_local_heads();
2805 struct refspec refspec = REFSPEC_INIT_PUSH;
2806
2807 refspec_appendn(&refspec, argv + 2, argc - 2);
2808
2809 for (i = 0; i < refspec.nr; i++) {
2810 const struct refspec_item *rs = &refspec.items[i];
2811
2812 if (rs->pattern || rs->matching)
2813 continue;
2814
2815 /* LHS must match a single ref */
2816 switch (count_refspec_match(rs->src, local_refs, NULL)) {
2817 case 1:
2818 break;
2819 case 0:
2820 /*
2821 * If LHS matches 'HEAD' then we need to ensure
2822 * that it matches the same named branch
2823 * checked out in the superproject.
2824 */
2825 if (!strcmp(rs->src, "HEAD")) {
2826 if (!detached_head &&
2827 !strcmp(head, superproject_head))
2828 break;
2829 die("HEAD does not match the named branch in the superproject");
2830 }
2831 /* fallthrough */
2832 default:
2833 die("src refspec '%s' must name a ref",
2834 rs->src);
2835 }
2836 }
2837 refspec_clear(&refspec);
2838 }
2839 free(head);
2840
2841 return 0;
2842 }
2843
2844 static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
2845 {
2846 int i;
2847 struct pathspec pathspec = { 0 };
2848 struct module_list list = MODULE_LIST_INIT;
2849 const char *super_prefix = NULL;
2850 struct option embed_gitdir_options[] = {
2851 OPT__SUPER_PREFIX(&super_prefix),
2852 OPT_END()
2853 };
2854 const char *const git_submodule_helper_usage[] = {
2855 N_("git submodule absorbgitdirs [<options>] [<path>...]"),
2856 NULL
2857 };
2858 int ret = 1;
2859
2860 argc = parse_options(argc, argv, prefix, embed_gitdir_options,
2861 git_submodule_helper_usage, 0);
2862
2863 if (module_list_compute(argv, prefix, &pathspec, &list) < 0)
2864 goto cleanup;
2865
2866 for (i = 0; i < list.nr; i++)
2867 absorb_git_dir_into_superproject(list.entries[i]->name,
2868 super_prefix);
2869
2870 ret = 0;
2871 cleanup:
2872 clear_pathspec(&pathspec);
2873 module_list_release(&list);
2874 return ret;
2875 }
2876
2877 static int module_set_url(int argc, const char **argv, const char *prefix)
2878 {
2879 int quiet = 0;
2880 const char *newurl;
2881 const char *path;
2882 char *config_name;
2883 struct option options[] = {
2884 OPT__QUIET(&quiet, N_("suppress output for setting url of a submodule")),
2885 OPT_END()
2886 };
2887 const char *const usage[] = {
2888 N_("git submodule set-url [--quiet] <path> <newurl>"),
2889 NULL
2890 };
2891
2892 argc = parse_options(argc, argv, prefix, options, usage, 0);
2893
2894 if (argc != 2 || !(path = argv[0]) || !(newurl = argv[1]))
2895 usage_with_options(usage, options);
2896
2897 config_name = xstrfmt("submodule.%s.url", path);
2898
2899 config_set_in_gitmodules_file_gently(config_name, newurl);
2900 sync_submodule(path, prefix, NULL, quiet ? OPT_QUIET : 0);
2901
2902 free(config_name);
2903
2904 return 0;
2905 }
2906
2907 static int module_set_branch(int argc, const char **argv, const char *prefix)
2908 {
2909 int opt_default = 0, ret;
2910 const char *opt_branch = NULL;
2911 const char *path;
2912 char *config_name;
2913 struct option options[] = {
2914 /*
2915 * We accept the `quiet` option for uniformity across subcommands,
2916 * though there is nothing to make less verbose in this subcommand.
2917 */
2918 OPT_NOOP_NOARG('q', "quiet"),
2919
2920 OPT_BOOL('d', "default", &opt_default,
2921 N_("set the default tracking branch to master")),
2922 OPT_STRING('b', "branch", &opt_branch, N_("branch"),
2923 N_("set the default tracking branch")),
2924 OPT_END()
2925 };
2926 const char *const usage[] = {
2927 N_("git submodule set-branch [-q|--quiet] (-d|--default) <path>"),
2928 N_("git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"),
2929 NULL
2930 };
2931
2932 argc = parse_options(argc, argv, prefix, options, usage, 0);
2933
2934 if (!opt_branch && !opt_default)
2935 die(_("--branch or --default required"));
2936
2937 if (opt_branch && opt_default)
2938 die(_("options '%s' and '%s' cannot be used together"), "--branch", "--default");
2939
2940 if (argc != 1 || !(path = argv[0]))
2941 usage_with_options(usage, options);
2942
2943 config_name = xstrfmt("submodule.%s.branch", path);
2944 ret = config_set_in_gitmodules_file_gently(config_name, opt_branch);
2945
2946 free(config_name);
2947 return !!ret;
2948 }
2949
2950 static int module_create_branch(int argc, const char **argv, const char *prefix)
2951 {
2952 enum branch_track track;
2953 int quiet = 0, force = 0, reflog = 0, dry_run = 0;
2954 struct option options[] = {
2955 OPT__QUIET(&quiet, N_("print only error messages")),
2956 OPT__FORCE(&force, N_("force creation"), 0),
2957 OPT_BOOL(0, "create-reflog", &reflog,
2958 N_("create the branch's reflog")),
2959 OPT_CALLBACK_F('t', "track", &track, "(direct|inherit)",
2960 N_("set branch tracking configuration"),
2961 PARSE_OPT_OPTARG,
2962 parse_opt_tracking_mode),
2963 OPT__DRY_RUN(&dry_run,
2964 N_("show whether the branch would be created")),
2965 OPT_END()
2966 };
2967 const char *const usage[] = {
2968 N_("git submodule--helper create-branch [-f|--force] [--create-reflog] [-q|--quiet] [-t|--track] [-n|--dry-run] <name> <start-oid> <start-name>"),
2969 NULL
2970 };
2971
2972 git_config(git_default_config, NULL);
2973 track = git_branch_track;
2974 argc = parse_options(argc, argv, prefix, options, usage, 0);
2975
2976 if (argc != 3)
2977 usage_with_options(usage, options);
2978
2979 if (!quiet && !dry_run)
2980 printf_ln(_("creating branch '%s'"), argv[0]);
2981
2982 create_branches_recursively(the_repository, argv[0], argv[1], argv[2],
2983 force, reflog, quiet, track, dry_run);
2984 return 0;
2985 }
2986
2987 struct add_data {
2988 const char *prefix;
2989 const char *branch;
2990 const char *reference_path;
2991 char *sm_path;
2992 const char *sm_name;
2993 const char *repo;
2994 const char *realrepo;
2995 int depth;
2996 unsigned int force: 1;
2997 unsigned int quiet: 1;
2998 unsigned int progress: 1;
2999 unsigned int dissociate: 1;
3000 };
3001 #define ADD_DATA_INIT { .depth = -1 }
3002
3003 static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path)
3004 {
3005 struct child_process cp_remote = CHILD_PROCESS_INIT;
3006 struct strbuf sb_remote_out = STRBUF_INIT;
3007
3008 cp_remote.git_cmd = 1;
3009 strvec_pushf(&cp_remote.env,
3010 "GIT_DIR=%s", git_dir_path);
3011 strvec_push(&cp_remote.env, "GIT_WORK_TREE=.");
3012 strvec_pushl(&cp_remote.args, "remote", "-v", NULL);
3013 if (!capture_command(&cp_remote, &sb_remote_out, 0)) {
3014 char *next_line;
3015 char *line = sb_remote_out.buf;
3016
3017 while ((next_line = strchr(line, '\n')) != NULL) {
3018 size_t len = next_line - line;
3019
3020 if (strip_suffix_mem(line, &len, " (fetch)"))
3021 strbuf_addf(msg, " %.*s\n", (int)len, line);
3022 line = next_line + 1;
3023 }
3024 }
3025
3026 strbuf_release(&sb_remote_out);
3027 }
3028
3029 static int add_submodule(const struct add_data *add_data)
3030 {
3031 char *submod_gitdir_path;
3032 struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;
3033 struct string_list reference = STRING_LIST_INIT_NODUP;
3034 int ret = -1;
3035
3036 /* perhaps the path already exists and is already a git repo, else clone it */
3037 if (is_directory(add_data->sm_path)) {
3038 struct strbuf sm_path = STRBUF_INIT;
3039 strbuf_addstr(&sm_path, add_data->sm_path);
3040 submod_gitdir_path = xstrfmt("%s/.git", add_data->sm_path);
3041 if (is_nonbare_repository_dir(&sm_path))
3042 printf(_("Adding existing repo at '%s' to the index\n"),
3043 add_data->sm_path);
3044 else
3045 die(_("'%s' already exists and is not a valid git repo"),
3046 add_data->sm_path);
3047 strbuf_release(&sm_path);
3048 free(submod_gitdir_path);
3049 } else {
3050 struct child_process cp = CHILD_PROCESS_INIT;
3051
3052 submod_gitdir_path = xstrfmt(".git/modules/%s", add_data->sm_name);
3053
3054 if (is_directory(submod_gitdir_path)) {
3055 if (!add_data->force) {
3056 struct strbuf msg = STRBUF_INIT;
3057 char *die_msg;
3058
3059 strbuf_addf(&msg, _("A git directory for '%s' is found "
3060 "locally with remote(s):\n"),
3061 add_data->sm_name);
3062
3063 append_fetch_remotes(&msg, submod_gitdir_path);
3064 free(submod_gitdir_path);
3065
3066 strbuf_addf(&msg, _("If you want to reuse this local git "
3067 "directory instead of cloning again from\n"
3068 " %s\n"
3069 "use the '--force' option. If the local git "
3070 "directory is not the correct repo\n"
3071 "or you are unsure what this means choose "
3072 "another name with the '--name' option."),
3073 add_data->realrepo);
3074
3075 die_msg = strbuf_detach(&msg, NULL);
3076 die("%s", die_msg);
3077 } else {
3078 printf(_("Reactivating local git directory for "
3079 "submodule '%s'\n"), add_data->sm_name);
3080 }
3081 }
3082 free(submod_gitdir_path);
3083
3084 clone_data.prefix = add_data->prefix;
3085 clone_data.path = add_data->sm_path;
3086 clone_data.name = add_data->sm_name;
3087 clone_data.url = add_data->realrepo;
3088 clone_data.quiet = add_data->quiet;
3089 clone_data.progress = add_data->progress;
3090 if (add_data->reference_path) {
3091 char *p = xstrdup(add_data->reference_path);
3092
3093 string_list_append(&reference, p)->util = p;
3094 }
3095 clone_data.dissociate = add_data->dissociate;
3096 if (add_data->depth >= 0)
3097 clone_data.depth = xstrfmt("%d", add_data->depth);
3098
3099 if (clone_submodule(&clone_data, &reference))
3100 goto cleanup;
3101
3102 prepare_submodule_repo_env(&cp.env);
3103 cp.git_cmd = 1;
3104 cp.dir = add_data->sm_path;
3105 /*
3106 * NOTE: we only get here if add_data->force is true, so
3107 * passing --force to checkout is reasonable.
3108 */
3109 strvec_pushl(&cp.args, "checkout", "-f", "-q", NULL);
3110
3111 if (add_data->branch) {
3112 strvec_pushl(&cp.args, "-B", add_data->branch, NULL);
3113 strvec_pushf(&cp.args, "origin/%s", add_data->branch);
3114 }
3115
3116 if (run_command(&cp))
3117 die(_("unable to checkout submodule '%s'"), add_data->sm_path);
3118 }
3119 ret = 0;
3120 cleanup:
3121 string_list_clear(&reference, 1);
3122 return ret;
3123 }
3124
3125 static int config_submodule_in_gitmodules(const char *name, const char *var, const char *value)
3126 {
3127 char *key;
3128 int ret;
3129
3130 if (!is_writing_gitmodules_ok())
3131 die(_("please make sure that the .gitmodules file is in the working tree"));
3132
3133 key = xstrfmt("submodule.%s.%s", name, var);
3134 ret = config_set_in_gitmodules_file_gently(key, value);
3135 free(key);
3136
3137 return ret;
3138 }
3139
3140 static void configure_added_submodule(struct add_data *add_data)
3141 {
3142 char *key;
3143 const char *val;
3144 struct child_process add_submod = CHILD_PROCESS_INIT;
3145 struct child_process add_gitmodules = CHILD_PROCESS_INIT;
3146
3147 key = xstrfmt("submodule.%s.url", add_data->sm_name);
3148 git_config_set_gently(key, add_data->realrepo);
3149 free(key);
3150
3151 add_submod.git_cmd = 1;
3152 strvec_pushl(&add_submod.args, "add",
3153 "--no-warn-embedded-repo", NULL);
3154 if (add_data->force)
3155 strvec_push(&add_submod.args, "--force");
3156 strvec_pushl(&add_submod.args, "--", add_data->sm_path, NULL);
3157
3158 if (run_command(&add_submod))
3159 die(_("Failed to add submodule '%s'"), add_data->sm_path);
3160
3161 if (config_submodule_in_gitmodules(add_data->sm_name, "path", add_data->sm_path) ||
3162 config_submodule_in_gitmodules(add_data->sm_name, "url", add_data->repo))
3163 die(_("Failed to register submodule '%s'"), add_data->sm_path);
3164
3165 if (add_data->branch) {
3166 if (config_submodule_in_gitmodules(add_data->sm_name,
3167 "branch", add_data->branch))
3168 die(_("Failed to register submodule '%s'"), add_data->sm_path);
3169 }
3170
3171 add_gitmodules.git_cmd = 1;
3172 strvec_pushl(&add_gitmodules.args,
3173 "add", "--force", "--", ".gitmodules", NULL);
3174
3175 if (run_command(&add_gitmodules))
3176 die(_("Failed to register submodule '%s'"), add_data->sm_path);
3177
3178 /*
3179 * NEEDSWORK: In a multi-working-tree world this needs to be
3180 * set in the per-worktree config.
3181 */
3182 /*
3183 * NEEDSWORK: In the longer run, we need to get rid of this
3184 * pattern of querying "submodule.active" before calling
3185 * is_submodule_active(), since that function needs to find
3186 * out the value of "submodule.active" again anyway.
3187 */
3188 if (!git_config_get_string_tmp("submodule.active", &val)) {
3189 /*
3190 * If the submodule being added isn't already covered by the
3191 * current configured pathspec, set the submodule's active flag
3192 */
3193 if (!is_submodule_active(the_repository, add_data->sm_path)) {
3194 key = xstrfmt("submodule.%s.active", add_data->sm_name);
3195 git_config_set_gently(key, "true");
3196 free(key);
3197 }
3198 } else {
3199 key = xstrfmt("submodule.%s.active", add_data->sm_name);
3200 git_config_set_gently(key, "true");
3201 free(key);
3202 }
3203 }
3204
3205 static void die_on_index_match(const char *path, int force)
3206 {
3207 struct pathspec ps;
3208 const char *args[] = { path, NULL };
3209 parse_pathspec(&ps, 0, PATHSPEC_PREFER_CWD, NULL, args);
3210
3211 if (repo_read_index_preload(the_repository, NULL, 0) < 0)
3212 die(_("index file corrupt"));
3213
3214 if (ps.nr) {
3215 int i;
3216 char *ps_matched = xcalloc(ps.nr, 1);
3217
3218 /* TODO: audit for interaction with sparse-index. */
3219 ensure_full_index(&the_index);
3220
3221 /*
3222 * Since there is only one pathspec, we just need to
3223 * check ps_matched[0] to know if a cache entry matched.
3224 */
3225 for (i = 0; i < the_index.cache_nr; i++) {
3226 ce_path_match(&the_index, the_index.cache[i], &ps,
3227 ps_matched);
3228
3229 if (ps_matched[0]) {
3230 if (!force)
3231 die(_("'%s' already exists in the index"),
3232 path);
3233 if (!S_ISGITLINK(the_index.cache[i]->ce_mode))
3234 die(_("'%s' already exists in the index "
3235 "and is not a submodule"), path);
3236 break;
3237 }
3238 }
3239 free(ps_matched);
3240 }
3241 clear_pathspec(&ps);
3242 }
3243
3244 static void die_on_repo_without_commits(const char *path)
3245 {
3246 struct strbuf sb = STRBUF_INIT;
3247 strbuf_addstr(&sb, path);
3248 if (is_nonbare_repository_dir(&sb)) {
3249 struct object_id oid;
3250 if (resolve_gitlink_ref(path, "HEAD", &oid) < 0)
3251 die(_("'%s' does not have a commit checked out"), path);
3252 }
3253 strbuf_release(&sb);
3254 }
3255
3256 static int module_add(int argc, const char **argv, const char *prefix)
3257 {
3258 int force = 0, quiet = 0, progress = 0, dissociate = 0;
3259 struct add_data add_data = ADD_DATA_INIT;
3260 char *to_free = NULL;
3261 struct option options[] = {
3262 OPT_STRING('b', "branch", &add_data.branch, N_("branch"),
3263 N_("branch of repository to add as submodule")),
3264 OPT__FORCE(&force, N_("allow adding an otherwise ignored submodule path"),
3265 PARSE_OPT_NOCOMPLETE),
3266 OPT__QUIET(&quiet, N_("print only error messages")),
3267 OPT_BOOL(0, "progress", &progress, N_("force cloning progress")),
3268 OPT_STRING(0, "reference", &add_data.reference_path, N_("repository"),
3269 N_("reference repository")),
3270 OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")),
3271 OPT_STRING(0, "name", &add_data.sm_name, N_("name"),
3272 N_("sets the submodule's name to the given string "
3273 "instead of defaulting to its path")),
3274 OPT_INTEGER(0, "depth", &add_data.depth, N_("depth for shallow clones")),
3275 OPT_END()
3276 };
3277 const char *const usage[] = {
3278 N_("git submodule add [<options>] [--] <repository> [<path>]"),
3279 NULL
3280 };
3281 struct strbuf sb = STRBUF_INIT;
3282 int ret = 1;
3283
3284 argc = parse_options(argc, argv, prefix, options, usage, 0);
3285
3286 if (!is_writing_gitmodules_ok())
3287 die(_("please make sure that the .gitmodules file is in the working tree"));
3288
3289 if (prefix && *prefix &&
3290 add_data.reference_path && !is_absolute_path(add_data.reference_path))
3291 add_data.reference_path = xstrfmt("%s%s", prefix, add_data.reference_path);
3292
3293 if (argc == 0 || argc > 2)
3294 usage_with_options(usage, options);
3295
3296 add_data.repo = argv[0];
3297 if (argc == 1)
3298 add_data.sm_path = git_url_basename(add_data.repo, 0, 0);
3299 else
3300 add_data.sm_path = xstrdup(argv[1]);
3301
3302 if (prefix && *prefix && !is_absolute_path(add_data.sm_path)) {
3303 char *sm_path = add_data.sm_path;
3304
3305 add_data.sm_path = xstrfmt("%s%s", prefix, sm_path);
3306 free(sm_path);
3307 }
3308
3309 if (starts_with_dot_dot_slash(add_data.repo) ||
3310 starts_with_dot_slash(add_data.repo)) {
3311 if (prefix)
3312 die(_("Relative path can only be used from the toplevel "
3313 "of the working tree"));
3314
3315 /* dereference source url relative to parent's url */
3316 to_free = resolve_relative_url(add_data.repo, NULL, 1);
3317 add_data.realrepo = to_free;
3318 } else if (is_dir_sep(add_data.repo[0]) || strchr(add_data.repo, ':')) {
3319 add_data.realrepo = add_data.repo;
3320 } else {
3321 die(_("repo URL: '%s' must be absolute or begin with ./|../"),
3322 add_data.repo);
3323 }
3324
3325 /*
3326 * normalize path:
3327 * multiple //; leading ./; /./; /../;
3328 */
3329 normalize_path_copy(add_data.sm_path, add_data.sm_path);
3330 strip_dir_trailing_slashes(add_data.sm_path);
3331
3332 die_on_index_match(add_data.sm_path, force);
3333 die_on_repo_without_commits(add_data.sm_path);
3334
3335 if (!force) {
3336 struct child_process cp = CHILD_PROCESS_INIT;
3337
3338 cp.git_cmd = 1;
3339 cp.no_stdout = 1;
3340 strvec_pushl(&cp.args, "add", "--dry-run", "--ignore-missing",
3341 "--no-warn-embedded-repo", add_data.sm_path, NULL);
3342 if ((ret = pipe_command(&cp, NULL, 0, NULL, 0, &sb, 0))) {
3343 strbuf_complete_line(&sb);
3344 fputs(sb.buf, stderr);
3345 goto cleanup;
3346 }
3347 }
3348
3349 if(!add_data.sm_name)
3350 add_data.sm_name = add_data.sm_path;
3351
3352 if (check_submodule_name(add_data.sm_name))
3353 die(_("'%s' is not a valid submodule name"), add_data.sm_name);
3354
3355 add_data.prefix = prefix;
3356 add_data.force = !!force;
3357 add_data.quiet = !!quiet;
3358 add_data.progress = !!progress;
3359 add_data.dissociate = !!dissociate;
3360
3361 if (add_submodule(&add_data))
3362 goto cleanup;
3363 configure_added_submodule(&add_data);
3364
3365 ret = 0;
3366 cleanup:
3367 free(add_data.sm_path);
3368 free(to_free);
3369 strbuf_release(&sb);
3370
3371 return ret;
3372 }
3373
3374 int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
3375 {
3376 parse_opt_subcommand_fn *fn = NULL;
3377 const char *const usage[] = {
3378 N_("git submodule--helper <command>"),
3379 NULL
3380 };
3381 struct option options[] = {
3382 OPT_SUBCOMMAND("clone", &fn, module_clone),
3383 OPT_SUBCOMMAND("add", &fn, module_add),
3384 OPT_SUBCOMMAND("update", &fn, module_update),
3385 OPT_SUBCOMMAND("foreach", &fn, module_foreach),
3386 OPT_SUBCOMMAND("init", &fn, module_init),
3387 OPT_SUBCOMMAND("status", &fn, module_status),
3388 OPT_SUBCOMMAND("sync", &fn, module_sync),
3389 OPT_SUBCOMMAND("deinit", &fn, module_deinit),
3390 OPT_SUBCOMMAND("summary", &fn, module_summary),
3391 OPT_SUBCOMMAND("push-check", &fn, push_check),
3392 OPT_SUBCOMMAND("absorbgitdirs", &fn, absorb_git_dirs),
3393 OPT_SUBCOMMAND("set-url", &fn, module_set_url),
3394 OPT_SUBCOMMAND("set-branch", &fn, module_set_branch),
3395 OPT_SUBCOMMAND("create-branch", &fn, module_create_branch),
3396 OPT_END()
3397 };
3398 argc = parse_options(argc, argv, prefix, options, usage, 0);
3399
3400 return fn(argc, argv, prefix);
3401 }