[RFC_PATCHv4 5/7] submodule update: respect submodule.actionOnLabel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This change introduces the 'submodule.actionOnLabel' variable
in a repository configuration. Generally speaking 'submodule.actionOnLabel'
restricts the action of a command when no submodules are selected via the
command line explicitely to those submodules, which are selected by
'submodule.actionOnLabel'. It can occur multiple times and can specify
the path, the name or one of the labels of a submodule to select that
submodule.

The introduction of 'submodule.actionOnLabel' starts with
'git submodule update' in this patch and other commands will follow
in later patches.

'submodule.actionOnLabel' implies '--init' in 'git submodule update'.

Signed-off-by: Stefan Beller <sbeller@xxxxxxxxxx>

TODO: generic documentation for submodule.actionOnLabel
TODO: documentation for submodule update
Signed-off-by: Stefan Beller <sbeller@xxxxxxxxxx>
---
 builtin/submodule--helper.c |  22 ++++++++-
 t/t7400-submodule-basic.sh  | 115 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 136 insertions(+), 1 deletion(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index a69b1f4..93760ec 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -573,6 +573,8 @@ struct submodule_update_clone {
 	int current;
 	struct module_list list;
 	unsigned warn_if_uninitialized : 1;
+	/* patterns to initialize */
+	struct string_list *initialize;
 
 	/* update parameter passed via commandline */
 	struct submodule_update_strategy update;
@@ -590,7 +592,7 @@ struct submodule_update_clone {
 	/* If we want to stop as fast as possible and return an error */
 	unsigned quickstop : 1;
 };
-#define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
+#define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, NULL, \
 	SUBMODULE_UPDATE_STRATEGY_INIT, 0, NULL, NULL, NULL, NULL, \
 	STRING_LIST_INIT_DUP, 0}
 
@@ -644,6 +646,15 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 	strbuf_reset(&sb);
 	strbuf_addf(&sb, "submodule.%s.url", sub->name);
 	git_config_get_string(sb.buf, &url);
+	if (suc->initialize) {
+		if (!url) {
+			init_submodule(sub->path, suc->prefix, suc->quiet);
+			url = xstrdup(sub->url);
+		}
+		if (!submodule_applicable_by_labels(suc->initialize, sub)
+		    && !suc->warn_if_uninitialized)
+			goto cleanup;
+	}
 	if (!url) {
 		/*
 		 * Only mention uninitialized submodules when their
@@ -745,6 +756,7 @@ static int update_clone(int argc, const char **argv, const char *prefix)
 	const char *update = NULL;
 	int max_jobs = -1;
 	struct string_list_item *item;
+	const struct string_list *list;
 	struct pathspec pathspec;
 	struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT;
 
@@ -793,6 +805,14 @@ static int update_clone(int argc, const char **argv, const char *prefix)
 	gitmodules_config();
 	git_config(submodule_config, NULL);
 
+	list = git_config_get_value_multi("submodule.actionOnLabel");
+	if (list) {
+		suc.initialize = xmalloc(sizeof(*suc.initialize));
+		string_list_init(suc.initialize, 1);
+		for_each_string_list_item(item, list)
+			string_list_insert(suc.initialize, item->string);
+	}
+
 	if (max_jobs < 0)
 		max_jobs = parallel_submodules();
 
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index fc948fd..dc45551 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -1032,4 +1032,119 @@ test_expect_success 'submodule add records multiple labels' '
 	test_cmp expected actual
 '
 
+cat <<EOF > expected
+submodule
+-submodule2
+EOF
+
+test_expect_success 'update initializes all modules when action-on-label configured' '
+	test_when_finished "rm -rf super super_clone" &&
+	mkdir super &&
+	pwd=$(pwd) &&
+	(
+		cd super &&
+		git init &&
+		git submodule add --label labelA file://"$pwd"/example2 submodule &&
+		git submodule add file://"$pwd"/example2 submodule2 &&
+		git commit -a -m "add two modules, one is labled"
+	) &&
+	git clone super super_clone &&
+	(
+		cd super_clone &&
+		git config submodule.actionOnLabel \*labelA &&
+		git submodule update &&
+		git submodule status |cut -c1,42-52 | tr -d " " >../actual
+	) &&
+	test_cmp actual expected
+'
+
+test_expect_success 'submodule update applies to action-on-label selection' '
+	test_when_finished "rm -rf super super_clone" &&
+	mkdir super &&
+	oldSubmoduleHead=$(cd example2 && git rev-parse HEAD) &&
+	pwd=$(pwd) &&
+	(
+		cd super &&
+		git init &&
+		git submodule add --label labelA file://"$pwd"/example2 submodule1 &&
+		git submodule add --label labelA file://"$pwd"/example2 submodule2 &&
+		git submodule add --label labelA file://"$pwd"/example2 submodule3 &&
+		git commit -a -m "add two modules, both are labled"
+	) &&
+	git clone super super_clone &&
+	(
+		cd super_clone &&
+		git config submodule.actionOnLabel \*labelA &&
+		git submodule update
+	) &&
+	(
+		cd example2 &&
+		touch anotherfile &&
+		git add anotherfile &&
+		git commit -m "advance example2" &&
+		git checkout -b branchName
+	) &&
+	newSubmoduleHead=$(cd example2 && git rev-parse HEAD) &&
+	(
+		cd super &&
+		git submodule add --label labelA file://"$pwd"/example2 submodule4 &&
+		git commit -a -m "add another labeled module" &&
+		git config -f .gitmodules submodule.submodule2.label labelB &&
+		git config -f .gitmodules --unset submodule.submodule3.label &&
+		git commit -a -m "unlabel 2 and 3 upstream" &&
+		git submodule foreach git pull origin branchName &&
+		git commit -a -m "update all submodules" &&
+		git submodule status |cut -c1-52 >../actual
+	) &&
+	cat <<EOF >expected &&
+ $newSubmoduleHead submodule1
+ $newSubmoduleHead submodule2
+ $newSubmoduleHead submodule3
+ $newSubmoduleHead submodule4
+EOF
+	test_cmp actual expected &&
+	(
+		cd super_clone &&
+		git pull &&
+		git submodule update &&
+		git submodule status |cut -c1-52 >../actual
+	) &&
+	cat <<EOF >expected &&
+ $newSubmoduleHead submodule1
++$oldSubmoduleHead submodule2
++$oldSubmoduleHead submodule3
+ $newSubmoduleHead submodule4
+EOF
+	test_cmp actual expected
+'
+
+cat <<EOF > expected
+submodule1
+submodule2
+-submodule3
+EOF
+
+test_expect_success 'Change labels in .git/config' '
+	test_when_finished "rm -rf super super_clone" &&
+	mkdir super &&
+	pwd=$(pwd) &&
+	(
+		cd super &&
+		git init &&
+		git submodule add --label labelA file://"$pwd"/example2 submodule1 &&
+		git submodule add file://"$pwd"/example2 submodule2 &&
+		git submodule add file://"$pwd"/example2 submodule3 &&
+		git commit -a -m "add two modules, one is labled"
+	) &&
+	git clone super super_clone &&
+	(
+		cd super_clone &&
+		git config submodule.actionOnLabel \*labelA &&
+		git config submodule.submodule2.label labelA
+		git submodule update &&
+		git submodule status |cut -c1,42-52 | tr -d " " >../actual
+	) &&
+	test_cmp actual expected
+'
+
 test_done
-- 
2.7.0.rc0.45.g6b4c145

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]