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