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