submodule--helper update-clone: abort gracefully on missing .gitmodules

When there is no .gitmodules file availabe to initialize a submodule from, `submodule_from_path` just returns NULL. We need to check for that and abort gracefully. When `git submodule update` was implemented in shell, this error out with the warning Submodule path '%s' not initialized Maybe you want to use 'update --init'? Replicate that behavior for now instead of crashing. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Stefan Beller committed Apr 28, 2016 at 13:02 UTC 08fdbdb153c138f0a2dc85949475fafb20853d96
2 files changed +33 -13
builtin/submodule--helper.c
+25 -13
@@ -593,6 +593,25 @@ struct submodule_update_clone {
593 SUBMODULE_UPDATE_STRATEGY_INIT, 0, NULL, NULL, NULL, NULL, \
594 STRING_LIST_INIT_DUP, 0}
595
596 +
597 +static void next_submodule_warn_missing(struct submodule_update_clone *suc,
598 + struct strbuf *out, const char *displaypath)
599 +{
600 + /*
601 + * Only mention uninitialized submodules when their
602 + * paths have been specified.
603 + */
604 + if (suc->warn_if_uninitialized) {
605 + strbuf_addf(out,
606 + _("Submodule path '%s' not initialized"),
607 + displaypath);
608 + strbuf_addch(out, '\n');
609 + strbuf_addstr(out,
610 + _("Maybe you want to use 'update --init'?"));
611 + strbuf_addch(out, '\n');
612 + }
613 +}
614 +
615 /**
616 * Determine whether 'ce' needs to be cloned. If so, prepare the 'child' to
617 * run the clone. Returns 1 if 'ce' needs to be cloned, 0 otherwise.
@@ -627,6 +646,11 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
646 else
647 displaypath = ce->name;
648
649 + if (!sub) {
650 + next_submodule_warn_missing(suc, out, displaypath);
651 + goto cleanup;
652 + }
653 +
654 if (suc->update.type == SM_UPDATE_NONE
655 || (suc->update.type == SM_UPDATE_UNSPECIFIED
656 && sub->update_strategy.type == SM_UPDATE_NONE)) {
@@ -644,19 +668,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
668 strbuf_addf(&sb, "submodule.%s.url", sub->name);
669 git_config_get_string(sb.buf, &url);
670 if (!url) {
647 - /*
648 - * Only mention uninitialized submodules when their
649 - * path have been specified
650 - */
651 - if (suc->warn_if_uninitialized) {
652 - strbuf_addf(out,
653 - _("Submodule path '%s' not initialized"),
654 - displaypath);
655 - strbuf_addch(out, '\n');
656 - strbuf_addstr(out,
657 - _("Maybe you want to use 'update --init'?"));
658 - strbuf_addch(out, '\n');
659 - }
671 + next_submodule_warn_missing(suc, out, displaypath);
672 goto cleanup;
673 }
674
t/t7400-submodule-basic.sh
+8
@@ -26,6 +26,14 @@ test_expect_success 'submodule init aborts on missing .gitmodules file' '
26 test_i18ngrep "No url found for submodule path" actual
27 '
28
29 +test_expect_success 'submodule update aborts on missing .gitmodules file' '
30 + test_when_finished "git update-index --remove sub" &&
31 + git update-index --add --cacheinfo 160000,$(git rev-parse HEAD),sub &&
32 + # missing the .gitmodules file here
33 + git submodule update sub 2>actual &&
34 + test_i18ngrep "Submodule path .sub. not initialized" actual
35 +'
36 +
37 test_expect_success 'configuration parsing' '
38 test_when_finished "rm -f .gitmodules" &&
39 cat >.gitmodules <<-\EOF &&