submodule init: initialize active submodules

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@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Brandon Williams committed Mar 17, 2017 at 15:38 UTC 3e7eaed016e6241e96de6a0140923e81cfc387e8
3 files changed +90 -1
Documentation/git-submodule.txt
+3 -1
@@ -129,7 +129,9 @@ init [--] [<path>...]::
129 repository will be assumed to be upstream.
130 +
131 Optional <path> arguments limit which submodules will be initialized.
132 -If no path is specified, all submodules are initialized.
132 +If no path is specified and submodule.active has been configured, submodules
133 +configured to be active will be initialized, otherwise all submodules are
134 +initialized.
135 +
136 When present, it will also copy the value of `submodule.$name.update`.
137 This command does not alter existing information in .git/config.
builtin/submodule--helper.c
+30
@@ -270,6 +270,29 @@ static int module_list_compute(int argc, const char **argv,
270 return result;
271 }
272
273 +static void module_list_active(struct module_list *list)
274 +{
275 + int i;
276 + struct module_list active_modules = MODULE_LIST_INIT;
277 +
278 + gitmodules_config();
279 +
280 + for (i = 0; i < list->nr; i++) {
281 + const struct cache_entry *ce = list->entries[i];
282 +
283 + if (!is_submodule_initialized(ce->name))
284 + continue;
285 +
286 + ALLOC_GROW(active_modules.entries,
287 + active_modules.nr + 1,
288 + active_modules.alloc);
289 + active_modules.entries[active_modules.nr++] = ce;
290 + }
291 +
292 + free(list->entries);
293 + *list = active_modules;
294 +}
295 +
296 static int module_list(int argc, const char **argv, const char *prefix)
297 {
298 int i;
@@ -420,6 +443,13 @@ static int module_init(int argc, const char **argv, const char *prefix)
443 if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
444 return 1;
445
446 + /*
447 + * If there are no path args and submodule.active is set then,
448 + * by default, only initialize 'active' modules.
449 + */
450 + if (!argc && git_config_get_value_multi("submodule.active"))
451 + module_list_active(&list);
452 +
453 for (i = 0; i < list.nr; i++)
454 init_submodule(list.entries[i]->name, prefix, quiet);
455
t/t7400-submodule-basic.sh
+57
@@ -1130,5 +1130,62 @@ test_expect_success 'submodule helper list is not confused by common prefixes' '
1130 test_cmp expect actual
1131 '
1132
1133 +test_expect_success 'setup superproject with submodules' '
1134 + git init sub1 &&
1135 + test_commit -C sub1 test &&
1136 + test_commit -C sub1 test2 &&
1137 + git init multisuper &&
1138 + git -C multisuper submodule add ../sub1 sub0 &&
1139 + git -C multisuper submodule add ../sub1 sub1 &&
1140 + git -C multisuper submodule add ../sub1 sub2 &&
1141 + git -C multisuper submodule add ../sub1 sub3 &&
1142 + git -C multisuper commit -m "add some submodules"
1143 +'
1144 +
1145 +cat >expect <<-EOF
1146 +-sub0
1147 + sub1 (test2)
1148 + sub2 (test2)
1149 + sub3 (test2)
1150 +EOF
1151 +
1152 +test_expect_success 'submodule update --init with a specification' '
1153 + test_when_finished "rm -rf multisuper_clone" &&
1154 + pwd=$(pwd) &&
1155 + git clone file://"$pwd"/multisuper multisuper_clone &&
1156 + git -C multisuper_clone submodule update --init . ":(exclude)sub0" &&
1157 + git -C multisuper_clone submodule status |cut -c 1,43- >actual &&
1158 + test_cmp expect actual
1159 +'
1160 +
1161 +test_expect_success 'submodule update --init with submodule.active set' '
1162 + test_when_finished "rm -rf multisuper_clone" &&
1163 + pwd=$(pwd) &&
1164 + git clone file://"$pwd"/multisuper multisuper_clone &&
1165 + git -C multisuper_clone config submodule.active "." &&
1166 + git -C multisuper_clone config --add submodule.active ":(exclude)sub0" &&
1167 + git -C multisuper_clone submodule update --init &&
1168 + git -C multisuper_clone submodule status |cut -c 1,43- >actual &&
1169 + test_cmp expect actual
1170 +'
1171 +
1172 +test_expect_success 'submodule update and setting submodule.<name>.active' '
1173 + test_when_finished "rm -rf multisuper_clone" &&
1174 + pwd=$(pwd) &&
1175 + git clone file://"$pwd"/multisuper multisuper_clone &&
1176 + git -C multisuper_clone config --bool submodule.sub0.active "true" &&
1177 + git -C multisuper_clone config --bool submodule.sub1.active "false" &&
1178 + git -C multisuper_clone config --bool submodule.sub2.active "true" &&
1179 +
1180 + cat >expect <<-\EOF &&
1181 + sub0 (test2)
1182 + -sub1
1183 + sub2 (test2)
1184 + -sub3
1185 + EOF
1186 + git -C multisuper_clone submodule update &&
1187 + git -C multisuper_clone submodule status |cut -c 1,43- >actual &&
1188 + test_cmp expect actual
1189 +'
1190
1191 test_done