Changes in v5: * Add "NEEDSWORK" comments to indicate where attention is needed once per-worktree config is a reality * --no-recurse now works by clearing the string list of paths. * module_list_active() now does post-processing instead of duplicating code. Brandon Williams (10): submodule--helper: add is-active subcommand submodule status: use submodule--helper is-active submodule sync: skip work for inactive submodules submodule sync: use submodule--helper is-active submodule--helper clone: check for configured submodules using helper submodule: decouple url and submodule interest submodule init: initialize active submodules clone: teach --recurse-submodules to optionally take a pathspec submodule--helper init: set submodule.<name>.active submodule add: respect submodule.active and submodule.<name>.active Documentation/config.txt | 15 ++++- Documentation/git-clone.txt | 14 +++-- Documentation/git-submodule.txt | 4 +- builtin/clone.c | 50 ++++++++++++--- builtin/submodule--helper.c | 68 ++++++++++++++++---- git-submodule.sh | 55 ++++++++++------ submodule.c | 50 ++++++++++++--- t/t7400-submodule-basic.sh | 136 ++++++++++++++++++++++++++++++++++++++++ t/t7413-submodule-is-active.sh | 107 +++++++++++++++++++++++++++++++ 9 files changed, 445 insertions(+), 54 deletions(-) create mode 100755 t/t7413-submodule-is-active.sh ---interdiff with 'origin/bw/submodule-is-active' diff --git a/builtin/clone.c b/builtin/clone.c index 3dc8faac5..a7be61d6b 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -62,9 +62,8 @@ static int recurse_submodules_cb(const struct option *opt, const char *arg, int unset) { if (unset) - return -1; - - if (arg) + string_list_clear((struct string_list *)opt->value, 0); + else if (arg) string_list_append((struct string_list *)opt->value, arg); else string_list_append((struct string_list *)opt->value, @@ -984,6 +983,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix) string_list_sort(&option_recurse_submodules); string_list_remove_duplicates(&option_recurse_submodules, 0); + /* + * NEEDSWORK: In a multi-working-tree world, this needs to be + * set in the per-worktree config. + */ for_each_string_list_item(item, &option_recurse_submodules) { strbuf_addf(&sb, "submodule.active=%s", item->string); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index a574596cb..7700d8948 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -273,29 +273,24 @@ static int module_list_compute(int argc, const char **argv, static void module_list_active(struct module_list *list) { int i; - - if (read_cache() < 0) - die(_("index file corrupt")); + struct module_list active_modules = MODULE_LIST_INIT; gitmodules_config(); - for (i = 0; i < active_nr; i++) { - const struct cache_entry *ce = active_cache[i]; + for (i = 0; i < list->nr; i++) { + const struct cache_entry *ce = list->entries[i]; - if (!S_ISGITLINK(ce->ce_mode) || - !is_submodule_initialized(ce->name)) + if (!is_submodule_initialized(ce->name)) continue; - ALLOC_GROW(list->entries, list->nr + 1, list->alloc); - list->entries[list->nr++] = ce; - while (i + 1 < active_nr && - !strcmp(ce->name, active_cache[i + 1]->name)) - /* - * Skip entries with the same name in different stages - * to make sure an entry is returned only once. - */ - i++; + 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) @@ -361,7 +356,12 @@ static void init_submodule(const char *path, const char *prefix, int quiet) die(_("No url found for submodule path '%s' in .gitmodules"), displaypath); - /* Set active flag for the submodule being initialized */ + /* + * NEEDSWORK: In a multi-working-tree world, this needs to be + * set in the per-worktree config. + * + * Set active flag for the submodule being initialized + */ if (!is_submodule_initialized(path)) { strbuf_reset(&sb); strbuf_addf(&sb, "submodule.%s.active", sub->name); @@ -452,14 +452,15 @@ static int module_init(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, module_init_options, git_submodule_helper_usage, 0); + 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); - else if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0) - return 1; for (i = 0; i < list.nr; i++) init_submodule(list.entries[i]->name, prefix, quiet); diff --git a/git-submodule.sh b/git-submodule.sh index 6eca93416..6ec35e5fc 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -279,6 +279,8 @@ or you are unsure what this means choose another name with the '--name' option." git add --force .gitmodules || die "$(eval_gettext "Failed to register submodule '\$sm_path'")" + # NEEDSWORK: In a multi-working-tree world, this needs to be + # set in the per-worktree config. if git config --get submodule.active >/dev/null then # If the submodule being adding isn't already covered by the -- 2.12.0.367.g23dc2f6d3c-goog