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>
This commit is contained in:
Brandon Williams 2017-03-17 15:38:02 -07:00 committed by Junio C Hamano
parent a086f921a7
commit 3e7eaed016
3 changed files with 90 additions and 1 deletions

View file

@ -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.

View file

@ -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);

View file

@ -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