Teach `submodule init` to initialize submodules which have been configured to be active by setting 'submodule.active' with a pathspec. Now if no path arguments are given and 'submodule.active' is configured, `init` will initialize all submodules which have been configured to be active. If no path arguments are given and 'submodule.active' is not configured, then `init` will retain the old behavior of initializing all submodules. This allows users to record more complex patterns as it saves retyping them whenever you invoke update. Signed-off-by: Brandon Williams <bmwill@xxxxxxxxxx> --- Documentation/git-submodule.txt | 4 ++- builtin/submodule--helper.c | 30 ++++++++++++++++++++++ t/t7400-submodule-basic.sh | 57 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index e05d0cdde..74bc6200d 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -129,7 +129,9 @@ init [--] [<path>...]:: repository will be assumed to be upstream. + Optional <path> arguments limit which submodules will be initialized. -If no path is specified, all submodules are initialized. +If no path is specified and submodule.active has been configured, submodules +configured to be active will be initialized, otherwise all submodules are +initialized. + When present, it will also copy the value of `submodule.$name.update`. This command does not alter existing information in .git/config. diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index f38e332c5..65208faa7 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -270,6 +270,29 @@ static int module_list_compute(int argc, const char **argv, return result; } +static void module_list_active(struct module_list *list) +{ + int i; + struct module_list active_modules = MODULE_LIST_INIT; + + gitmodules_config(); + + for (i = 0; i < list->nr; i++) { + const struct cache_entry *ce = list->entries[i]; + + if (!is_submodule_initialized(ce->name)) + continue; + + ALLOC_GROW(active_modules.entries, + active_modules.nr + 1, + active_modules.alloc); + active_modules.entries[active_modules.nr++] = ce; + } + + free(list->entries); + *list = active_modules; +} + static int module_list(int argc, const char **argv, const char *prefix) { int i; @@ -420,6 +443,13 @@ static int module_init(int argc, const char **argv, const char *prefix) if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0) return 1; + /* + * If there are no path args and submodule.active is set then, + * by default, only initialize 'active' modules. + */ + if (!argc && git_config_get_value_multi("submodule.active")) + module_list_active(&list); + for (i = 0; i < list.nr; i++) init_submodule(list.entries[i]->name, prefix, quiet); diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index c09ce0d4c..fbbe932d1 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -1130,5 +1130,62 @@ test_expect_success 'submodule helper list is not confused by common prefixes' ' test_cmp expect actual ' +test_expect_success 'setup superproject with submodules' ' + git init sub1 && + test_commit -C sub1 test && + test_commit -C sub1 test2 && + git init multisuper && + git -C multisuper submodule add ../sub1 sub0 && + git -C multisuper submodule add ../sub1 sub1 && + git -C multisuper submodule add ../sub1 sub2 && + git -C multisuper submodule add ../sub1 sub3 && + git -C multisuper commit -m "add some submodules" +' + +cat >expect <<-EOF +-sub0 + sub1 (test2) + sub2 (test2) + sub3 (test2) +EOF + +test_expect_success 'submodule update --init with a specification' ' + test_when_finished "rm -rf multisuper_clone" && + pwd=$(pwd) && + git clone file://"$pwd"/multisuper multisuper_clone && + git -C multisuper_clone submodule update --init . ":(exclude)sub0" && + git -C multisuper_clone submodule status |cut -c 1,43- >actual && + test_cmp expect actual +' + +test_expect_success 'submodule update --init with submodule.active set' ' + test_when_finished "rm -rf multisuper_clone" && + pwd=$(pwd) && + git clone file://"$pwd"/multisuper multisuper_clone && + git -C multisuper_clone config submodule.active "." && + git -C multisuper_clone config --add submodule.active ":(exclude)sub0" && + git -C multisuper_clone submodule update --init && + git -C multisuper_clone submodule status |cut -c 1,43- >actual && + test_cmp expect actual +' + +test_expect_success 'submodule update and setting submodule.<name>.active' ' + test_when_finished "rm -rf multisuper_clone" && + pwd=$(pwd) && + git clone file://"$pwd"/multisuper multisuper_clone && + git -C multisuper_clone config --bool submodule.sub0.active "true" && + git -C multisuper_clone config --bool submodule.sub1.active "false" && + git -C multisuper_clone config --bool submodule.sub2.active "true" && + + cat >expect <<-\EOF && + sub0 (test2) + -sub1 + sub2 (test2) + -sub3 + EOF + git -C multisuper_clone submodule update && + git -C multisuper_clone submodule status |cut -c 1,43- >actual && + test_cmp expect actual +' test_done -- 2.12.0.367.g23dc2f6d3c-goog