Subject: [PATCH v5 00/10] decoupling url and submodule interest

From: Brandon Williams <[email-masked]>
Date: Fri, 17 Mar 2017 15:37:55 -0700

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