All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brandon Williams <bmwill@google.com>
To: git@vger.kernel.org
Cc: Brandon Williams <bmwill@google.com>,
	sbeller@google.com, gitster@pobox.com
Subject: [PATCH v4 08/10] clone: teach --recurse-submodules to optionally take a pathspec
Date: Thu, 16 Mar 2017 15:29:50 -0700	[thread overview]
Message-ID: <20170316222952.53801-9-bmwill@google.com> (raw)
In-Reply-To: <20170316222952.53801-1-bmwill@google.com>

Teach clone --recurse-submodules to optionally take a pathspec argument
which describes which submodules should be recursively initialized and
cloned.  If no pathspec is provided, --recurse-submodules will
recursively initialize and clone all submodules by using a default
pathspec of ".".  In order to construct more complex pathspecs,
--recurse-submodules can be given multiple times.

Additionally this configures the 'submodule.active' configuration option
to be the given pathspec, such that any future invocation of `git
submodule update` will keep up with the pathspec.

Signed-off-by: Brandon Williams <bmwill@google.com>
---
 Documentation/git-clone.txt | 14 ++++++----
 builtin/clone.c             | 47 ++++++++++++++++++++++++++-----
 t/t7400-submodule-basic.sh  | 68 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+), 12 deletions(-)

diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 35cc34b2f..30052cce4 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -14,7 +14,7 @@ SYNOPSIS
 	  [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
 	  [--dissociate] [--separate-git-dir <git dir>]
 	  [--depth <depth>] [--[no-]single-branch]
-	  [--recursive | --recurse-submodules] [--[no-]shallow-submodules]
+	  [--recurse-submodules] [--[no-]shallow-submodules]
 	  [--jobs <n>] [--] <repository> [<directory>]
 
 DESCRIPTION
@@ -215,10 +215,14 @@ objects from the source repository into a pack in the cloned repository.
 	branch when `--single-branch` clone was made, no remote-tracking
 	branch is created.
 
---recursive::
---recurse-submodules::
-	After the clone is created, initialize all submodules within,
-	using their default settings. This is equivalent to running
+--recurse-submodules[=<pathspec]::
+	After the clone is created, initialize and clone submodules
+	within based on the provided pathspec.  If no pathspec is
+	provided, all submodules are initialized and cloned.
+	Submodules are initialized and cloned using their default
+	settings.  The resulting clone has `submodule.active` set to
+	the provided pathspec, or "." (meaning all submodules) if no
+	pathspec is provided.  This is equivalent to running
 	`git submodule update --init --recursive` immediately after
 	the clone is finished. This option is ignored if the cloned
 	repository does not have a worktree/checkout (i.e. if any of
diff --git a/builtin/clone.c b/builtin/clone.c
index 3f63edbbf..3dc8faac5 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -39,7 +39,7 @@ static const char * const builtin_clone_usage[] = {
 };
 
 static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1;
-static int option_local = -1, option_no_hardlinks, option_shared, option_recursive;
+static int option_local = -1, option_no_hardlinks, option_shared;
 static int option_shallow_submodules;
 static int deepen;
 static char *option_template, *option_depth, *option_since;
@@ -56,6 +56,22 @@ static struct string_list option_required_reference = STRING_LIST_INIT_NODUP;
 static struct string_list option_optional_reference = STRING_LIST_INIT_NODUP;
 static int option_dissociate;
 static int max_jobs = -1;
+static struct string_list option_recurse_submodules = STRING_LIST_INIT_NODUP;
+
+static int recurse_submodules_cb(const struct option *opt,
+				 const char *arg, int unset)
+{
+	if (unset)
+		return -1;
+
+	if (arg)
+		string_list_append((struct string_list *)opt->value, arg);
+	else
+		string_list_append((struct string_list *)opt->value,
+				   (const char *)opt->defval);
+
+	return 0;
+}
 
 static struct option builtin_clone_options[] = {
 	OPT__VERBOSITY(&option_verbosity),
@@ -74,10 +90,13 @@ static struct option builtin_clone_options[] = {
 		    N_("don't use local hardlinks, always copy")),
 	OPT_BOOL('s', "shared", &option_shared,
 		    N_("setup as shared repository")),
-	OPT_BOOL(0, "recursive", &option_recursive,
-		    N_("initialize submodules in the clone")),
-	OPT_BOOL(0, "recurse-submodules", &option_recursive,
-		    N_("initialize submodules in the clone")),
+	{ OPTION_CALLBACK, 0, "recursive", &option_recurse_submodules,
+	  N_("pathspec"), N_("initialize submodules in the clone"),
+	  PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN, recurse_submodules_cb,
+	  (intptr_t)"." },
+	{ OPTION_CALLBACK, 0, "recurse-submodules", &option_recurse_submodules,
+	  N_("pathspec"), N_("initialize submodules in the clone"),
+	  PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)"." },
 	OPT_INTEGER('j', "jobs", &max_jobs,
 		    N_("number of submodules cloned in parallel")),
 	OPT_STRING(0, "template", &option_template, N_("template-directory"),
@@ -733,7 +752,7 @@ static int checkout(int submodule_progress)
 	err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1),
 			   sha1_to_hex(sha1), "1", NULL);
 
-	if (!err && option_recursive) {
+	if (!err && (option_recurse_submodules.nr > 0)) {
 		struct argv_array args = ARGV_ARRAY_INIT;
 		argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL);
 
@@ -957,7 +976,21 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 			fprintf(stderr, _("Cloning into '%s'...\n"), dir);
 	}
 
-	if (option_recursive) {
+	if (option_recurse_submodules.nr > 0) {
+		struct string_list_item *item;
+		struct strbuf sb = STRBUF_INIT;
+
+		/* remove duplicates */
+		string_list_sort(&option_recurse_submodules);
+		string_list_remove_duplicates(&option_recurse_submodules, 0);
+
+		for_each_string_list_item(item, &option_recurse_submodules) {
+			strbuf_addf(&sb, "submodule.active=%s",
+				    item->string);
+			string_list_append(&option_config,
+					   strbuf_detach(&sb, NULL));
+		}
+
 		if (option_required_reference.nr &&
 		    option_optional_reference.nr)
 			die(_("clone --recursive is not compatible with "
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index fbbe932d1..3af1c00ff 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -1188,4 +1188,72 @@ test_expect_success 'submodule update and setting submodule.<name>.active' '
 	test_cmp expect actual
 '
 
+test_expect_success 'clone --recurse-submodules with a pathspec works' '
+	test_when_finished "rm -rf multisuper_clone" &&
+	cat >expected <<-\EOF &&
+	 sub0 (test2)
+	-sub1
+	-sub2
+	-sub3
+	EOF
+
+	git clone --recurse-submodules="sub0" multisuper multisuper_clone &&
+	git -C multisuper_clone submodule status |cut -c1,43- >actual &&
+	test_cmp actual expected
+'
+
+test_expect_success 'clone with multiple --recurse-submodules options' '
+	test_when_finished "rm -rf multisuper_clone" &&
+	cat >expect <<-\EOF &&
+	-sub0
+	 sub1 (test2)
+	-sub2
+	 sub3 (test2)
+	EOF
+
+	git clone --recurse-submodules="." \
+		  --recurse-submodules=":(exclude)sub0" \
+		  --recurse-submodules=":(exclude)sub2" \
+		  multisuper multisuper_clone &&
+	git -C multisuper_clone submodule status |cut -c1,43- >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'clone and subsequent updates correctly auto-initialize submodules' '
+	test_when_finished "rm -rf multisuper_clone" &&
+	cat <<-\EOF >expect &&
+	-sub0
+	 sub1 (test2)
+	-sub2
+	 sub3 (test2)
+	EOF
+
+	cat <<-\EOF >expect2 &&
+	-sub0
+	 sub1 (test2)
+	-sub2
+	 sub3 (test2)
+	-sub4
+	 sub5 (test2)
+	EOF
+
+	git clone --recurse-submodules="." \
+		  --recurse-submodules=":(exclude)sub0" \
+		  --recurse-submodules=":(exclude)sub2" \
+		  --recurse-submodules=":(exclude)sub4" \
+		  multisuper multisuper_clone &&
+
+	git -C multisuper_clone submodule status |cut -c1,43- >actual &&
+	test_cmp expect actual &&
+
+	git -C multisuper submodule add ../sub1 sub4 &&
+	git -C multisuper submodule add ../sub1 sub5 &&
+	git -C multisuper commit -m "add more submodules" &&
+	# obtain the new superproject
+	git -C multisuper_clone pull &&
+	git -C multisuper_clone submodule update --init &&
+	git -C multisuper_clone submodule status |cut -c1,43- >actual &&
+	test_cmp expect2 actual
+'
+
 test_done
-- 
2.12.0.367.g23dc2f6d3c-goog


  parent reply	other threads:[~2017-03-16 22:37 UTC|newest]

Thread overview: 123+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-23 23:47 [PATCH 00/10] decoupling a submodule's existence and its url Brandon Williams
2017-02-23 23:47 ` [PATCH 01/10] submodule: decouple url and submodule existence Brandon Williams
2017-02-24 21:02   ` Junio C Hamano
2017-03-01 20:02     ` Brandon Williams
2017-03-01 21:53       ` Stefan Beller
2017-03-06 18:50         ` Brandon Williams
2017-03-02  5:43       ` Junio C Hamano
2017-02-23 23:47 ` [PATCH 02/10] submodule update: add `--init-active` switch Brandon Williams
2017-02-23 23:47 ` [PATCH 03/10] clone: add --submodule-spec=<pathspec> switch Brandon Williams
2017-02-23 23:47 ` [PATCH 04/10] completion: clone can initialize specific submodules Brandon Williams
2017-02-23 23:47 ` [PATCH 05/10] submodule--helper: add is_active command Brandon Williams
2017-02-24  1:15   ` Stefan Beller
2017-02-27 18:35     ` Brandon Williams
2017-02-23 23:47 ` [PATCH 06/10] submodule add: respect submodule.active Brandon Williams
2017-02-23 23:47 ` [PATCH 07/10] submodule status: use submodule--helper is-active Brandon Williams
2017-02-23 23:47 ` [PATCH 08/10] submodule deinit: use most reliable url Brandon Williams
2017-02-23 23:47 ` [PATCH 09/10] submodule sync: use submodule--helper is-active Brandon Williams
2017-02-23 23:47 ` [PATCH 10/10] submodule--helper clone: check for configured submodules using helper Brandon Williams
2017-02-24  0:58   ` Stefan Beller
2017-02-27 18:38     ` Brandon Williams
2017-02-23 23:58 ` [PATCH 00/10] decoupling a submodule's existence and its url Stefan Beller
2017-03-09  1:23 ` [PATCH v2 00/11] " Brandon Williams
2017-03-09  1:23   ` [PATCH v2 01/11] submodule--helper: add is_active command Brandon Williams
2017-03-09  1:23   ` [PATCH v2 02/11] submodule status: use submodule--helper is-active Brandon Williams
2017-03-09  1:23   ` [PATCH v2 03/11] submodule deinit: use most reliable url Brandon Williams
2017-03-09  1:56     ` Stefan Beller
2017-03-09 18:15       ` Brandon Williams
2017-03-09  1:23   ` [PATCH v2 04/11] submodule sync: use submodule--helper is-active Brandon Williams
2017-03-09  1:23   ` [PATCH v2 05/11] submodule--helper clone: check for configured submodules using helper Brandon Williams
2017-03-09  1:23   ` [PATCH v2 06/11] submodule: decouple url and submodule existence Brandon Williams
2017-03-09  1:23   ` [PATCH v2 07/11] submodule update: add `--init-active` switch Brandon Williams
2017-03-09  2:16     ` Stefan Beller
2017-03-09 18:08       ` Brandon Williams
2017-03-09  1:23   ` [PATCH v2 08/11] clone: add --submodule-spec=<pathspec> switch Brandon Williams
2017-03-09  1:23   ` [PATCH v2 09/11] completion: clone can initialize specific submodules Brandon Williams
2017-03-09  1:23   ` [PATCH v2 10/11] submodule--helper init: set submodule.<name>.active Brandon Williams
2017-03-09  2:28     ` Stefan Beller
2017-03-09 17:56       ` Brandon Williams
2017-03-09  1:23   ` [PATCH v2 11/11] submodule add: respect submodule.active and submodule.<name>.active Brandon Williams
2017-03-13 21:43   ` [PATCH v3 00/10] decoupling a submodule's existence and its url Brandon Williams
2017-03-13 21:43     ` [PATCH v3 01/10] submodule--helper: add is_active command Brandon Williams
2017-03-13 22:36       ` Stefan Beller
2017-03-14 17:40       ` Junio C Hamano
2017-03-14 22:44         ` Brandon Williams
2017-03-13 21:43     ` [PATCH v3 02/10] submodule status: use submodule--helper is-active Brandon Williams
2017-03-14 17:46       ` Junio C Hamano
2017-03-14 18:16         ` Stefan Beller
2017-03-14 20:20           ` Junio C Hamano
2017-03-14 21:33           ` Junio C Hamano
2017-03-14 22:50         ` Brandon Williams
2017-03-14 23:36           ` Brandon Williams
2017-03-13 21:43     ` [PATCH v3 03/10] submodule sync: " Brandon Williams
2017-03-14 17:53       ` Junio C Hamano
2017-03-14 23:50         ` Brandon Williams
2017-03-13 21:43     ` [PATCH v3 04/10] submodule--helper clone: check for configured submodules using helper Brandon Williams
2017-03-14 18:06       ` Junio C Hamano
2017-03-14 18:40         ` Stefan Beller
2017-03-14 20:25           ` Junio C Hamano
2017-03-15  0:10           ` Brandon Williams
2017-03-13 21:43     ` [PATCH v3 05/10] submodule: decouple url and submodule existence Brandon Williams
2017-03-13 22:49       ` Stefan Beller
2017-03-15 17:38         ` Brandon Williams
2017-03-14 18:42       ` Junio C Hamano
2017-03-14 21:38         ` Junio C Hamano
2017-03-15 21:37         ` Brandon Williams
2017-03-13 21:43     ` [PATCH v3 06/10] submodule update: add `--init-active` switch Brandon Williams
2017-03-14 19:18       ` Junio C Hamano
2017-03-15 21:52         ` Brandon Williams
2017-03-14 19:28       ` Junio C Hamano
2017-03-15 21:42         ` Brandon Williams
2017-03-13 21:43     ` [PATCH v3 07/10] clone: add --submodule-spec=<pathspec> switch Brandon Williams
2017-03-14 19:38       ` Junio C Hamano
2017-03-15 23:08         ` Brandon Williams
2017-03-15 23:25           ` Stefan Beller
2017-03-13 21:43     ` [PATCH v3 08/10] completion: clone can initialize specific submodules Brandon Williams
2017-03-13 21:43     ` [PATCH v3 09/10] submodule--helper init: set submodule.<name>.active Brandon Williams
2017-03-14 19:43       ` Junio C Hamano
2017-03-15 22:46         ` Brandon Williams
2017-03-16 16:47           ` Junio C Hamano
2017-03-13 21:43     ` [PATCH v3 10/10] submodule add: respect submodule.active and submodule.<name>.active Brandon Williams
2017-03-14 19:48       ` Junio C Hamano
2017-03-15 21:59         ` Brandon Williams
2017-03-13 22:51     ` [PATCH v3 00/10] decoupling a submodule's existence and its url Stefan Beller
2017-03-14 21:40     ` Junio C Hamano
2017-03-14 22:17       ` Brandon Williams
2017-03-16 22:29     ` [PATCH v4 00/10] decoupling url and submodule interest Brandon Williams
2017-03-16 22:29       ` [PATCH v4 01/10] submodule--helper: add is-active subcommand Brandon Williams
2017-03-16 22:29       ` [PATCH v4 02/10] submodule status: use submodule--helper is-active Brandon Williams
2017-03-16 22:29       ` [PATCH v4 03/10] submodule sync: skip work for inactive submodules Brandon Williams
2017-03-16 23:24         ` Stefan Beller
2017-03-16 23:25           ` Stefan Beller
2017-03-16 23:26           ` Brandon Williams
2017-03-17  5:26           ` Junio C Hamano
2017-03-17  6:58             ` Brandon Williams
2017-03-17 17:28               ` Junio C Hamano
2017-03-16 22:29       ` [PATCH v4 04/10] submodule sync: use submodule--helper is-active Brandon Williams
2017-03-16 22:29       ` [PATCH v4 05/10] submodule--helper clone: check for configured submodules using helper Brandon Williams
2017-03-16 22:29       ` [PATCH v4 06/10] submodule: decouple url and submodule interest Brandon Williams
2017-03-16 23:45         ` Stefan Beller
2017-03-16 22:29       ` [PATCH v4 07/10] submodule init: initialize active submodules Brandon Williams
2017-03-17 18:17         ` Stefan Beller
2017-03-17 22:28           ` Brandon Williams
2017-03-17 23:25             ` Stefan Beller
2017-03-16 22:29       ` Brandon Williams [this message]
2017-03-17 17:37         ` [PATCH v4 08/10] clone: teach --recurse-submodules to optionally take a pathspec Stefan Beller
2017-03-17 21:28           ` Brandon Williams
2017-03-16 22:29       ` [PATCH v4 09/10] submodule--helper init: set submodule.<name>.active Brandon Williams
2017-03-17 17:22         ` Stefan Beller
2017-03-17 21:55           ` Brandon Williams
2017-03-16 22:29       ` [PATCH v4 10/10] submodule add: respect submodule.active and submodule.<name>.active Brandon Williams
2017-03-17 22:37       ` [PATCH v5 00/10] decoupling url and submodule interest Brandon Williams
2017-03-17 22:37         ` [PATCH v5 01/10] submodule--helper: add is-active subcommand Brandon Williams
2017-03-17 22:37         ` [PATCH v5 02/10] submodule status: use submodule--helper is-active Brandon Williams
2017-03-17 22:37         ` [PATCH v5 03/10] submodule sync: skip work for inactive submodules Brandon Williams
2017-03-17 22:37         ` [PATCH v5 04/10] submodule sync: use submodule--helper is-active Brandon Williams
2017-03-17 22:38         ` [PATCH v5 05/10] submodule--helper clone: check for configured submodules using helper Brandon Williams
2017-03-17 22:38         ` [PATCH v5 06/10] submodule: decouple url and submodule interest Brandon Williams
2017-03-17 22:38         ` [PATCH v5 07/10] submodule init: initialize active submodules Brandon Williams
2017-03-17 22:38         ` [PATCH v5 08/10] clone: teach --recurse-submodules to optionally take a pathspec Brandon Williams
2017-03-17 22:38         ` [PATCH v5 09/10] submodule--helper init: set submodule.<name>.active Brandon Williams
2017-03-17 22:38         ` [PATCH v5 10/10] submodule add: respect submodule.active and submodule.<name>.active Brandon Williams
2017-03-17 23:25         ` [PATCH v5 00/10] decoupling url and submodule interest Stefan Beller
2017-03-18 17:00         ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170316222952.53801-9-bmwill@google.com \
    --to=bmwill@google.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=sbeller@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.