[RFC PATCH 2/4] fetch: refactor --submodule-prefix

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

 



Since "git fetch" learned to recurse into submodules [1], it has passed
"--submodule-prefix=<path from root of superproject tree to submodule>"
to print full paths to the submodules being fetched. This is the same
value as "--super-prefix"'s when calling "git read-tree
--recurse-submodules", as well as "git (grep|ls-files)
--recurse-submodules" before they were implemented in-process [2] [3],
(when they used repository.submodule_prefix to replace "--super-prefix).

Let's standardize the way we pass such prefixes. Having a per-command
"--submodule-prefix" is preferable to a top-level "--super-prefix",
since it gives us fine-grained control over which commands support it
and which don't, and we can preserve the effort-saving properties of the
top-level flag by sharing an implementation under the hood.

Refactor "git fetch" so that "--submodule-prefix" is stored in
repository.submodule_prefix, and create functions in submodule.h for
parsing and reading its value. Also, mark it with PARSE_OPT_HIDDEN and
drop it from our documentation. We will follow this pattern for "git
read-tree" in the next commit.

Since we've previously documented that repository.submodule_prefix is
only set for submodules, introduce repository.is_submodule for
distinguishing between the_repository and a submodule (although, this
turns out to be unused, since no caller uses repository.submodule_prefix
for that purpose).

[1] 7dce19d374 (fetch/pull: Add the --recurse-submodules option, 2010-11-12)
[2] 188dce131f (ls-files: use repository object, 2017-06-22)
[3] f9ee2fcdfa (grep: recurse in-process using 'struct repository', 2017-08-02)

Signed-off-by: Glen Choo <chooglen@xxxxxxxxxx>
---
 Documentation/fetch-options.txt |  5 -----
 builtin/fetch.c                 |  7 +++----
 repository.c                    |  1 +
 repository.h                    |  9 +++++++--
 submodule.c                     | 35 +++++++++++++++++++++------------
 submodule.h                     | 12 +++++++++--
 6 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 622bd84768..20cbd2c291 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -241,11 +241,6 @@ endif::git-pull[]
 	linkgit:git-config[1].
 
 ifndef::git-pull[]
---submodule-prefix=<path>::
-	Prepend <path> to paths printed in informative messages
-	such as "Fetching submodule foo".  This option is used
-	internally when recursing over submodules.
-
 --recurse-submodules-default=[yes|on-demand]::
 	This option is used internally to temporarily provide a
 	non-negative default value for the --recurse-submodules
diff --git a/builtin/fetch.c b/builtin/fetch.c
index b06e454cbd..78a46389ff 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -74,7 +74,6 @@ static struct string_list deepen_not = STRING_LIST_INIT_NODUP;
 static struct strbuf default_rla = STRBUF_INIT;
 static struct transport *gtransport;
 static struct transport *gsecondary;
-static const char *submodule_prefix = "";
 static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
 static int recurse_submodules_cli = RECURSE_SUBMODULES_DEFAULT;
 static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
@@ -195,8 +194,9 @@ static struct option builtin_fetch_options[] = {
 	OPT_SET_INT_F(0, "refetch", &refetch,
 		      N_("re-fetch without negotiating common commits"),
 		      1, PARSE_OPT_NONEG),
-	{ OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, N_("dir"),
-		   N_("prepend this to submodule path output"), PARSE_OPT_HIDDEN },
+	OPT_CALLBACK_F(0, "submodule-prefix", NULL, "path",
+			"path from top-level superproject root to current repo root",
+			PARSE_OPT_HIDDEN, option_parse_submodule_prefix),
 	OPT_CALLBACK_F(0, "recurse-submodules-default",
 		   &recurse_submodules_default, N_("on-demand"),
 		   N_("default for recursive fetching of submodules "
@@ -2297,7 +2297,6 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 		add_options_to_argv(&options);
 		result = fetch_submodules(the_repository,
 					  &options,
-					  submodule_prefix,
 					  recurse_submodules,
 					  recurse_submodules_default,
 					  verbosity < 0,
diff --git a/repository.c b/repository.c
index 5d166b692c..1d454a0ac4 100644
--- a/repository.c
+++ b/repository.c
@@ -229,6 +229,7 @@ int repo_submodule_init(struct repository *subrepo,
 		}
 	}
 
+	subrepo->is_submodule = 1;
 	subrepo->submodule_prefix = xstrfmt("%s%s/",
 					    superproject->submodule_prefix ?
 					    superproject->submodule_prefix :
diff --git a/repository.h b/repository.h
index 24316ac944..1bc4afc2b6 100644
--- a/repository.h
+++ b/repository.h
@@ -119,10 +119,15 @@ struct repository {
 	 */
 	char *worktree;
 
+	/*
+	 * Whether this struct represents a submodule of this process's main
+	 * repository.
+	 */
+	int is_submodule;
+
 	/*
 	 * Path from the root of the top-level superproject down to this
-	 * repository.  This is only non-NULL if the repository is initialized
-	 * as a submodule of another repository.
+	 * repository.
 	 */
 	char *submodule_prefix;
 
diff --git a/submodule.c b/submodule.c
index a6db8c4bbe..d84345a0b4 100644
--- a/submodule.c
+++ b/submodule.c
@@ -257,6 +257,21 @@ const char *get_toplevel_cwd_prefix(void)
 	return toplevel_cwd_prefix;
 }
 
+int option_parse_submodule_prefix(const struct option *opt,
+				  const char *arg, int unset)
+{
+	if (arg)
+		the_repository->submodule_prefix = xstrdup(arg);
+	return 0;
+}
+
+const char *get_submodule_prefix(void)
+{
+	if (!the_repository->submodule_prefix)
+		return "";
+	return the_repository->submodule_prefix;
+}
+
 /*
  * Determine if a submodule has been initialized at a given 'path'
  */
@@ -1392,7 +1407,6 @@ struct submodule_parallel_fetch {
 	int changed_count;
 	struct strvec args;
 	struct repository *r;
-	const char *prefix;
 	int command_line_option;
 	int default_option;
 	int quiet;
@@ -1583,7 +1597,7 @@ get_fetch_task_from_index(struct submodule_parallel_fetch *spf,
 		if (task->repo) {
 			if (!spf->quiet)
 				strbuf_addf(err, _("Fetching submodule %s%s\n"),
-					    spf->prefix, ce->name);
+					    get_submodule_prefix(), ce->name);
 
 			spf->index_count++;
 			return task;
@@ -1645,7 +1659,7 @@ get_fetch_task_from_changed(struct submodule_parallel_fetch *spf,
 		if (!spf->quiet)
 			strbuf_addf(err,
 				    _("Fetching submodule %s%s at commit %s\n"),
-				    spf->prefix, task->sub->path,
+				    get_submodule_prefix(), task->sub->path,
 				    find_unique_abbrev(cs_data->super_oid,
 						       DEFAULT_ABBREV));
 
@@ -1692,8 +1706,6 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err,
 		task = get_fetch_task_from_changed(spf, err);
 
 	if (task) {
-		struct strbuf submodule_prefix = STRBUF_INIT;
-
 		child_process_init(cp);
 		cp->dir = task->repo->gitdir;
 		prepare_submodule_repo_env_in_gitdir(&cp->env);
@@ -1705,13 +1717,11 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err,
 		strvec_push(&cp->args, task->default_argv);
 		strvec_push(&cp->args, "--submodule-prefix");
 
-		strbuf_addf(&submodule_prefix, "%s%s/",
-						spf->prefix,
-						task->sub->path);
-		strvec_push(&cp->args, submodule_prefix.buf);
+		strvec_pushf(&cp->args, "%s%s/",
+					get_submodule_prefix(),
+					task->sub->path);
 		*task_cb = task;
 
-		strbuf_release(&submodule_prefix);
 		string_list_insert(&spf->seen_submodule_names, task->sub->name);
 		return 1;
 	}
@@ -1723,7 +1733,7 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err,
 		spf->oid_fetch_tasks_nr--;
 
 		strbuf_addf(&submodule_prefix, "%s%s/",
-			    spf->prefix, task->sub->path);
+			    get_submodule_prefix(), task->sub->path);
 
 		child_process_init(cp);
 		prepare_submodule_repo_env_in_gitdir(&cp->env);
@@ -1829,7 +1839,7 @@ static int fetch_finish(int retvalue, struct strbuf *err,
 
 int fetch_submodules(struct repository *r,
 		     const struct strvec *options,
-		     const char *prefix, int command_line_option,
+		     int command_line_option,
 		     int default_option,
 		     int quiet, int max_parallel_jobs)
 {
@@ -1851,7 +1861,6 @@ int fetch_submodules(struct repository *r,
 	spf.command_line_option = command_line_option;
 	spf.default_option = default_option;
 	spf.quiet = quiet;
-	spf.prefix = prefix;
 
 	if (!r->worktree)
 		goto out;
diff --git a/submodule.h b/submodule.h
index 436dbb2e11..f2701c4869 100644
--- a/submodule.h
+++ b/submodule.h
@@ -55,7 +55,7 @@ struct option;
 int option_parse_recurse_submodules_worktree_updater(const struct option *opt,
 						     const char *arg, int unset);
 int option_parse_toplevel_cwd_prefix(const struct option *opt,
-				   const char *arg, int unset);
+				     const char *arg, int unset);
 /*
  * Return the relative path of the top-level process's cwd to the root of the
  * working tree. When printing paths to submodules in the working tree, this
@@ -63,6 +63,15 @@ int option_parse_toplevel_cwd_prefix(const struct option *opt,
  * top-level process's cwd instead of this process's cwd.
  */
 const char *get_toplevel_cwd_prefix(void);
+int option_parse_submodule_prefix(const struct option *opt,
+				      const char *arg, int unset);
+/*
+ * Return the path from the root of the top-level superproject to root of this
+ * repository. When printing paths to submodules in a tree, this value should be
+ * prepended to the path so that they originate from the top-level
+ * superproject's tree instead of this repository's tree.
+ */
+const char *get_submodule_prefix(void);
 
 int is_tree_submodule_active(struct repository *repo,
 			     const struct object_id *treeish_name,
@@ -100,7 +109,6 @@ const struct submodule *submodule_from_ce(const struct cache_entry *ce);
 void check_for_new_submodule_commits(struct object_id *oid);
 int fetch_submodules(struct repository *r,
 		     const struct strvec *options,
-		     const char *prefix,
 		     int command_line_option,
 		     int default_option,
 		     int quiet, int max_parallel_jobs);
-- 
2.38.1.431.g37b22c650d-goog




[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]

  Powered by Linux