git@vger.kernel.org mailing list mirror (one of many)
 help / Atom feed
* [PATCH 0/2] clone: record submodule alternates when not recursing
@ 2017-04-11 19:46 Stefan Beller
  2017-04-11 19:46 ` [PATCH 1/2] submodule.c: add has_submodules to check if we have any submodules Stefan Beller
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Stefan Beller @ 2017-04-11 19:46 UTC (permalink / raw)
  To: bmwill, maxime.viargues; +Cc: git, Stefan Beller

The meat is in the second patch:
    The commit 31224cbdc7 (clone: recursive and reference option triggers
    submodule alternates, 2016-08-17) argued for any further `submodule update`
    to respect the initial setup. This is not the case if you only pass
    '--reference[-if-able]' to the initial clone without instructing to
    recurse into submodules.
    
    If there are submodules however the user is likely to later run
    a 'submodule update --init' to obtain the submodules. In this case we
    also want to have the references available.

The first patch produces a nice helper function and some refactoring.

Thanks,
Stefan

Stefan Beller (2):
  submodule.c: add has_submodules to check if we have any submodules
  clone: remember references for submodules even when not recursing

 builtin/checkout.c          |  2 +-
 builtin/clone.c             |  8 +++--
 builtin/fetch.c             |  2 +-
 builtin/read-tree.c         |  2 +-
 builtin/submodule--helper.c |  6 ++--
 submodule.c                 | 78 +++++++++++++++++++++++++++++++++++----------
 submodule.h                 |  8 ++++-
 unpack-trees.c              |  2 +-
 8 files changed, 82 insertions(+), 26 deletions(-)

-- 
2.12.2.575.gb14f27f917


^ permalink raw reply	[flat|threaded] 9+ messages in thread

* [PATCH 1/2] submodule.c: add has_submodules to check if we have any submodules
  2017-04-11 19:46 [PATCH 0/2] clone: record submodule alternates when not recursing Stefan Beller
@ 2017-04-11 19:46 ` Stefan Beller
  2017-04-20 22:07   ` Brandon Williams
  2017-04-11 19:46 ` [PATCH 2/2] clone: remember references for submodules even when not recursing Stefan Beller
  2017-04-19 19:52 ` [PATCH 0/2] clone: record submodule alternates " Stefan Beller
  2 siblings, 1 reply; 9+ messages in thread
From: Stefan Beller @ 2017-04-11 19:46 UTC (permalink / raw)
  To: bmwill, maxime.viargues; +Cc: git, Stefan Beller

When submodules are involved, it often slows down the process, as most
submodule related handling is either done via a child process or by
iterating over the index finding all gitlinks.

For most commands that may interact with submodules, we need have a
quick check if we do have any submodules at all, such that we can
be fast in the case when no submodules are in use.  For this quick
check introduce a function that checks with different heuristics if
we do have submodules around, checking if
* anything related to submodules is configured,
* absorbed git dirs for submodules are present,
* the '.gitmodules' file exists
* gitlinks are recorded in the index.

Each heuristic has advantages and disadvantages.
For example in a later patch, when we first use this function in
git-clone, we'll just check for the existence of the '.gitmodules'
file, because at the time of running the clone command there will
be no absorbed git dirs or submodule configuration around.

Checking for any configuration related to submodules would be useful
in a later stage (after cloning) to see if the submodules are actually
in use.

Checking for absorbed git directories is good to see if the user has
actually cloned submodules already (i.e. not just initialized them by
configuring them).

The heuristic for checking the configuration requires this patch
to have have a global state, whether the submodule config has already
been read, and if there were any submodule related keys. Make
'submodule_config' private to the submodule code, and introduce
'load_submodule_config' that will take care of this global state.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/checkout.c          |  2 +-
 builtin/fetch.c             |  2 +-
 builtin/read-tree.c         |  2 +-
 builtin/submodule--helper.c |  6 ++--
 submodule.c                 | 78 +++++++++++++++++++++++++++++++++++----------
 submodule.h                 |  8 ++++-
 unpack-trees.c              |  2 +-
 7 files changed, 76 insertions(+), 24 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 3ecc47bec0..cd5a2fd75a 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1216,7 +1216,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 	}
 
 	if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
-		git_config(submodule_config, NULL);
+		load_submodule_config();
 		if (recurse_submodules != RECURSE_SUBMODULES_DEFAULT)
 			set_config_update_recurse_submodules(recurse_submodules);
 	}
diff --git a/builtin/fetch.c b/builtin/fetch.c
index b5ad09d046..0bf3aa4458 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1342,7 +1342,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 			set_config_fetch_recurse_submodules(arg);
 		}
 		gitmodules_config();
-		git_config(submodule_config, NULL);
+		load_submodule_config();
 	}
 
 	if (all) {
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index 23e212ee8c..fe2ec60a51 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -177,7 +177,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 
 	if (recurse_submodules != RECURSE_SUBMODULES_DEFAULT) {
 		gitmodules_config();
-		git_config(submodule_config, NULL);
+		load_submodule_config();
 		set_config_update_recurse_submodules(RECURSE_SUBMODULES_ON);
 	}
 
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 85aafe46a4..770a95ca14 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1015,7 +1015,7 @@ static int update_clone(int argc, const char **argv, const char *prefix)
 
 	/* Overlay the parsed .gitmodules file with .git/config */
 	gitmodules_config();
-	git_config(submodule_config, NULL);
+	load_submodule_config();
 
 	if (max_jobs < 0)
 		max_jobs = parallel_submodules();
@@ -1058,7 +1058,7 @@ static const char *remote_submodule_branch(const char *path)
 {
 	const struct submodule *sub;
 	gitmodules_config();
-	git_config(submodule_config, NULL);
+	load_submodule_config();
 
 	sub = submodule_from_path(null_sha1, path);
 	if (!sub)
@@ -1130,7 +1130,7 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
 			     git_submodule_helper_usage, 0);
 
 	gitmodules_config();
-	git_config(submodule_config, NULL);
+	load_submodule_config();
 
 	if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
 		return 1;
diff --git a/submodule.c b/submodule.c
index c52d6634c5..da508dc257 100644
--- a/submodule.c
+++ b/submodule.c
@@ -24,6 +24,12 @@ static int initialized_fetch_ref_tips;
 static struct sha1_array ref_tips_before_fetch;
 static struct sha1_array ref_tips_after_fetch;
 
+static enum {
+	SUBMODULE_CONFIG_NOT_READ = 0,
+	SUBMODULE_CONFIG_NO_CONFIG,
+	SUBMODULE_CONFIG_EXISTS,
+} submodule_config_reading;
+
 /*
  * The following flag is set if the .gitmodules file is unmerged. We then
  * disable recursion for all submodules where .git/config doesn't have a
@@ -83,6 +89,62 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)
 	return 0;
 }
 
+static int submodule_config(const char *var, const char *value, void *cb)
+{
+	if (!strcmp(var, "submodule.fetchjobs")) {
+		submodule_config_reading = SUBMODULE_CONFIG_EXISTS;
+		parallel_jobs = git_config_int(var, value);
+		if (parallel_jobs < 0)
+			die(_("negative values not allowed for submodule.fetchJobs"));
+		return 0;
+	} else if (starts_with(var, "submodule.")) {
+		submodule_config_reading = SUBMODULE_CONFIG_EXISTS;
+		return parse_submodule_config_option(var, value);
+	} else if (!strcmp(var, "fetch.recursesubmodules")) {
+		submodule_config_reading = SUBMODULE_CONFIG_EXISTS;
+		config_fetch_recurse_submodules = parse_fetch_recurse_submodules_arg(var, value);
+		return 0;
+	}
+	return 0;
+}
+
+void load_submodule_config(void)
+{
+	submodule_config_reading = SUBMODULE_CONFIG_NO_CONFIG;
+	git_config(submodule_config, NULL);
+}
+
+int has_submodules(unsigned what_to_check)
+{
+	if (what_to_check & SUBMODULE_CHECK_ANY_CONFIG) {
+		if (submodule_config_reading == SUBMODULE_CONFIG_NOT_READ)
+			load_submodule_config();
+		if (submodule_config_reading == SUBMODULE_CONFIG_EXISTS)
+			return 1;
+	}
+
+	if ((what_to_check & SUBMODULE_CHECK_ABSORBED_GIT_DIRS) &&
+	    file_exists(git_path("modules")))
+		return 1;
+
+	if ((what_to_check & SUBMODULE_CHECK_GITMODULES_IN_WT) &&
+	    (!is_bare_repository() && file_exists(".gitmodules")))
+		return 1;
+
+	if (what_to_check & SUBMODULE_CHECK_GITLINKS_IN_TREE) {
+		int i;
+
+		if (read_cache() < 0)
+			die(_("index file corrupt"));
+
+		for (i = 0; i < active_nr; i++)
+			if (S_ISGITLINK(active_cache[i]->ce_mode))
+				return 1;
+	}
+
+	return 0;
+}
+
 /*
  * Try to remove the "submodule.<name>" section from .gitmodules where the given
  * path is configured. Return 0 only if a .gitmodules file was found, a section
@@ -152,22 +214,6 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
 	}
 }
 
-int submodule_config(const char *var, const char *value, void *cb)
-{
-	if (!strcmp(var, "submodule.fetchjobs")) {
-		parallel_jobs = git_config_int(var, value);
-		if (parallel_jobs < 0)
-			die(_("negative values not allowed for submodule.fetchJobs"));
-		return 0;
-	} else if (starts_with(var, "submodule."))
-		return parse_submodule_config_option(var, value);
-	else if (!strcmp(var, "fetch.recursesubmodules")) {
-		config_fetch_recurse_submodules = parse_fetch_recurse_submodules_arg(var, value);
-		return 0;
-	}
-	return 0;
-}
-
 void gitmodules_config(void)
 {
 	const char *work_tree = get_git_work_tree();
diff --git a/submodule.h b/submodule.h
index 8a8bc49dc9..5ec72fbb16 100644
--- a/submodule.h
+++ b/submodule.h
@@ -1,6 +1,12 @@
 #ifndef SUBMODULE_H
 #define SUBMODULE_H
 
+#define SUBMODULE_CHECK_ANY_CONFIG		(1<<0)
+#define SUBMODULE_CHECK_ABSORBED_GIT_DIRS	(1<<1)
+#define SUBMODULE_CHECK_GITMODULES_IN_WT	(1<<2)
+#define SUBMODULE_CHECK_GITLINKS_IN_TREE 	(1<<3)
+int has_submodules(unsigned what_to_check);
+
 struct diff_options;
 struct argv_array;
 struct sha1_array;
@@ -37,7 +43,7 @@ extern int remove_path_from_gitmodules(const char *path);
 extern void stage_updated_gitmodules(void);
 extern void set_diffopt_flags_from_submodule_config(struct diff_options *,
 		const char *path);
-extern int submodule_config(const char *var, const char *value, void *cb);
+extern void load_submodule_config(void);
 extern void gitmodules_config(void);
 extern void gitmodules_config_sha1(const unsigned char *commit_sha1);
 extern int is_submodule_initialized(const char *path);
diff --git a/unpack-trees.c b/unpack-trees.c
index 8333da2cc9..85af680cc9 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -288,7 +288,7 @@ static void reload_gitmodules_file(struct index_state *index,
 				submodule_free();
 				checkout_entry(ce, state, NULL);
 				gitmodules_config();
-				git_config(submodule_config, NULL);
+				load_submodule_config();
 			} else
 				break;
 		}
-- 
2.12.2.575.gb14f27f917


^ permalink raw reply	[flat|threaded] 9+ messages in thread

* [PATCH 2/2] clone: remember references for submodules even when not recursing
  2017-04-11 19:46 [PATCH 0/2] clone: record submodule alternates when not recursing Stefan Beller
  2017-04-11 19:46 ` [PATCH 1/2] submodule.c: add has_submodules to check if we have any submodules Stefan Beller
@ 2017-04-11 19:46 ` Stefan Beller
  2017-04-20 22:12   ` Brandon Williams
  2017-04-19 19:52 ` [PATCH 0/2] clone: record submodule alternates " Stefan Beller
  2 siblings, 1 reply; 9+ messages in thread
From: Stefan Beller @ 2017-04-11 19:46 UTC (permalink / raw)
  To: bmwill, maxime.viargues; +Cc: git, Stefan Beller

The commit 31224cbdc7 (clone: recursive and reference option triggers
submodule alternates, 2016-08-17) argued for any further `submodule update`
to respect the initial setup. This is not the case if you only pass
'--reference[-if-able]' to the initial clone without instructing to
recurse into submodules.

If there are submodules however the user is likely to later run
a 'submodule update --init' to obtain the submodules. In this case we
also want to have the references available.

Reported-by: Maxime Viargues <maxime.viargues@serato.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/clone.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/builtin/clone.c b/builtin/clone.c
index de85b85254..5f022e39e9 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -24,6 +24,7 @@
 #include "remote.h"
 #include "run-command.h"
 #include "connected.h"
+#include "submodule.h"
 
 /*
  * Overall FIXMEs:
@@ -993,11 +994,14 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 			string_list_append(&option_config,
 					   strbuf_detach(&sb, NULL));
 		}
+	}
 
+	if (option_recurse_submodules.nr ||
+	    has_submodules(SUBMODULE_CHECK_GITMODULES_IN_WT)) {
 		if (option_required_reference.nr &&
 		    option_optional_reference.nr)
-			die(_("clone --recursive is not compatible with "
-			      "both --reference and --reference-if-able"));
+			die(_("submodules are incompatible with both "
+			    "--reference and --reference-if-able"));
 		else if (option_required_reference.nr) {
 			string_list_append(&option_config,
 				"submodule.alternateLocation=superproject");
-- 
2.12.2.575.gb14f27f917


^ permalink raw reply	[flat|threaded] 9+ messages in thread

* Re: [PATCH 0/2] clone: record submodule alternates when not recursing
  2017-04-11 19:46 [PATCH 0/2] clone: record submodule alternates when not recursing Stefan Beller
  2017-04-11 19:46 ` [PATCH 1/2] submodule.c: add has_submodules to check if we have any submodules Stefan Beller
  2017-04-11 19:46 ` [PATCH 2/2] clone: remember references for submodules even when not recursing Stefan Beller
@ 2017-04-19 19:52 ` " Stefan Beller
  2 siblings, 0 replies; 9+ messages in thread
From: Stefan Beller @ 2017-04-19 19:52 UTC (permalink / raw)
  To: Brandon Williams, Maxime Viargues, Junio C Hamano, Jacob Keller; +Cc: git, Stefan Beller

+ Junio, Jacob

On Tue, Apr 11, 2017 at 12:46 PM, Stefan Beller <sbeller@google.com> wrote:
> The meat is in the second patch:
>     The commit 31224cbdc7 (clone: recursive and reference option triggers
>     submodule alternates, 2016-08-17) argued for any further `submodule update`
>     to respect the initial setup. This is not the case if you only pass
>     '--reference[-if-able]' to the initial clone without instructing to
>     recurse into submodules.
>
>     If there are submodules however the user is likely to later run
>     a 'submodule update --init' to obtain the submodules. In this case we
>     also want to have the references available.
>
> The first patch produces a nice helper function and some refactoring.
>
> Thanks,
> Stefan
>
> Stefan Beller (2):
>   submodule.c: add has_submodules to check if we have any submodules
>   clone: remember references for submodules even when not recursing
>
>  builtin/checkout.c          |  2 +-
>  builtin/clone.c             |  8 +++--
>  builtin/fetch.c             |  2 +-
>  builtin/read-tree.c         |  2 +-
>  builtin/submodule--helper.c |  6 ++--
>  submodule.c                 | 78 +++++++++++++++++++++++++++++++++++----------
>  submodule.h                 |  8 ++++-
>  unpack-trees.c              |  2 +-
>  8 files changed, 82 insertions(+), 26 deletions(-)
>
> --
> 2.12.2.575.gb14f27f917
>

^ permalink raw reply	[flat|threaded] 9+ messages in thread

* Re: [PATCH 1/2] submodule.c: add has_submodules to check if we have any submodules
  2017-04-11 19:46 ` [PATCH 1/2] submodule.c: add has_submodules to check if we have any submodules Stefan Beller
@ 2017-04-20 22:07   ` Brandon Williams
  2017-04-20 22:20     ` Stefan Beller
  0 siblings, 1 reply; 9+ messages in thread
From: Brandon Williams @ 2017-04-20 22:07 UTC (permalink / raw)
  To: Stefan Beller; +Cc: maxime.viargues, git

On 04/11, Stefan Beller wrote:
> +int has_submodules(unsigned what_to_check)
> +{
> +	if (what_to_check & SUBMODULE_CHECK_ANY_CONFIG) {
> +		if (submodule_config_reading == SUBMODULE_CONFIG_NOT_READ)
> +			load_submodule_config();
> +		if (submodule_config_reading == SUBMODULE_CONFIG_EXISTS)
> +			return 1;
> +	}
> +
> +	if ((what_to_check & SUBMODULE_CHECK_ABSORBED_GIT_DIRS) &&
> +	    file_exists(git_path("modules")))
> +		return 1;
> +
> +	if ((what_to_check & SUBMODULE_CHECK_GITMODULES_IN_WT) &&
> +	    (!is_bare_repository() && file_exists(".gitmodules")))
> +		return 1;
> +
> +	if (what_to_check & SUBMODULE_CHECK_GITLINKS_IN_TREE) {
> +		int i;
> +
> +		if (read_cache() < 0)
> +			die(_("index file corrupt"));
> +
> +		for (i = 0; i < active_nr; i++)
> +			if (S_ISGITLINK(active_cache[i]->ce_mode))
> +				return 1;
> +	}
> +
> +	return 0;
> +}

It may be a good idea to rearrange these by order to correctness.
Correctness may not be the best way to describe it, but which is the
strongest indicator that there is a submodule or that a repo 'has a
submodule'.  That way in the future we could have a #define that is
SUBMODULE_CHECK_ANY or ALL or something....Now that I'm thinking harder
about that we may not want that, and just require explicitly stating
which check you want done.

Anyways good looking patch, and I like the idea of consolidating the
checks into a single function.

> diff --git a/submodule.h b/submodule.h
> index 8a8bc49dc9..5ec72fbb16 100644
> --- a/submodule.h
> +++ b/submodule.h
> @@ -1,6 +1,12 @@
>  #ifndef SUBMODULE_H
>  #define SUBMODULE_H
>  
> +#define SUBMODULE_CHECK_ANY_CONFIG		(1<<0)
> +#define SUBMODULE_CHECK_ABSORBED_GIT_DIRS	(1<<1)
> +#define SUBMODULE_CHECK_GITMODULES_IN_WT	(1<<2)
> +#define SUBMODULE_CHECK_GITLINKS_IN_TREE 	(1<<3)
> +int has_submodules(unsigned what_to_check);

-- 
Brandon Williams

^ permalink raw reply	[flat|threaded] 9+ messages in thread

* Re: [PATCH 2/2] clone: remember references for submodules even when not recursing
  2017-04-11 19:46 ` [PATCH 2/2] clone: remember references for submodules even when not recursing Stefan Beller
@ 2017-04-20 22:12   ` Brandon Williams
  2017-04-20 22:28     ` Stefan Beller
  0 siblings, 1 reply; 9+ messages in thread
From: Brandon Williams @ 2017-04-20 22:12 UTC (permalink / raw)
  To: Stefan Beller; +Cc: maxime.viargues, git

On 04/11, Stefan Beller wrote:
> The commit 31224cbdc7 (clone: recursive and reference option triggers
> submodule alternates, 2016-08-17) argued for any further `submodule update`
> to respect the initial setup. This is not the case if you only pass
> '--reference[-if-able]' to the initial clone without instructing to
> recurse into submodules.
> 
> If there are submodules however the user is likely to later run
> a 'submodule update --init' to obtain the submodules. In this case we
> also want to have the references available.
> 

So the idea is to keep the references around even if the user doesn't
want to recurse immediately?

-- 
Brandon Williams

^ permalink raw reply	[flat|threaded] 9+ messages in thread

* Re: [PATCH 1/2] submodule.c: add has_submodules to check if we have any submodules
  2017-04-20 22:07   ` Brandon Williams
@ 2017-04-20 22:20     ` Stefan Beller
  2017-04-20 22:25       ` Brandon Williams
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Beller @ 2017-04-20 22:20 UTC (permalink / raw)
  To: Brandon Williams; +Cc: Maxime Viargues, git

On Thu, Apr 20, 2017 at 3:07 PM, Brandon Williams <bmwill@google.com> wrote:
> On 04/11, Stefan Beller wrote:
>> +int has_submodules(unsigned what_to_check)
>> +{
>> +     if (what_to_check & SUBMODULE_CHECK_ANY_CONFIG) {
>> +             if (submodule_config_reading == SUBMODULE_CONFIG_NOT_READ)
>> +                     load_submodule_config();
>> +             if (submodule_config_reading == SUBMODULE_CONFIG_EXISTS)
>> +                     return 1;
>> +     }
>> +
>> +     if ((what_to_check & SUBMODULE_CHECK_ABSORBED_GIT_DIRS) &&
>> +         file_exists(git_path("modules")))
>> +             return 1;
>> +
>> +     if ((what_to_check & SUBMODULE_CHECK_GITMODULES_IN_WT) &&
>> +         (!is_bare_repository() && file_exists(".gitmodules")))
>> +             return 1;
>> +
>> +     if (what_to_check & SUBMODULE_CHECK_GITLINKS_IN_TREE) {
>> +             int i;
>> +
>> +             if (read_cache() < 0)
>> +                     die(_("index file corrupt"));
>> +
>> +             for (i = 0; i < active_nr; i++)
>> +                     if (S_ISGITLINK(active_cache[i]->ce_mode))
>> +                             return 1;
>> +     }
>> +
>> +     return 0;
>> +}
>
> It may be a good idea to rearrange these by order to correctness.

I arranged by estimated speed, i.e. from fastest to slowest:
* The first check just returns a value from memory in the standard case
  Though the first one may take a hit in performance for the very first time
  as it may need to load the config.
* The next two are an actual stat system call, each having a different
  'defect'. (We may have non-absorbed submodules or non-bare repos)
  -> We could have a check for in-tree as well, not sure if that is desired.

> Correctness may not be the best way to describe it, but which is the
> strongest indicator that there is a submodule or that a repo 'has a
> submodule'.

These indicators differ in strength for different scenarios IMO.
(Just after clone: check for a .gitmodules file instead of a config;
later: rather check for a config as it is fastest and actually catches
active submodules; maybe we do not care about inactive submodules)

>  That way in the future we could have a #define that is
> SUBMODULE_CHECK_ANY or ALL or something....Now that I'm thinking harder
> about that we may not want that, and just require explicitly stating
> which check you want done.
>
> Anyways good looking patch, and I like the idea of consolidating the
> checks into a single function.

Thanks,
Stefan

^ permalink raw reply	[flat|threaded] 9+ messages in thread

* Re: [PATCH 1/2] submodule.c: add has_submodules to check if we have any submodules
  2017-04-20 22:20     ` Stefan Beller
@ 2017-04-20 22:25       ` Brandon Williams
  0 siblings, 0 replies; 9+ messages in thread
From: Brandon Williams @ 2017-04-20 22:25 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Maxime Viargues, git

On 04/20, Stefan Beller wrote:
> On Thu, Apr 20, 2017 at 3:07 PM, Brandon Williams <bmwill@google.com> wrote:
> > On 04/11, Stefan Beller wrote:
> >> +int has_submodules(unsigned what_to_check)
> >> +{
> >> +     if (what_to_check & SUBMODULE_CHECK_ANY_CONFIG) {
> >> +             if (submodule_config_reading == SUBMODULE_CONFIG_NOT_READ)
> >> +                     load_submodule_config();
> >> +             if (submodule_config_reading == SUBMODULE_CONFIG_EXISTS)
> >> +                     return 1;
> >> +     }
> >> +
> >> +     if ((what_to_check & SUBMODULE_CHECK_ABSORBED_GIT_DIRS) &&
> >> +         file_exists(git_path("modules")))
> >> +             return 1;
> >> +
> >> +     if ((what_to_check & SUBMODULE_CHECK_GITMODULES_IN_WT) &&
> >> +         (!is_bare_repository() && file_exists(".gitmodules")))
> >> +             return 1;
> >> +
> >> +     if (what_to_check & SUBMODULE_CHECK_GITLINKS_IN_TREE) {
> >> +             int i;
> >> +
> >> +             if (read_cache() < 0)
> >> +                     die(_("index file corrupt"));
> >> +
> >> +             for (i = 0; i < active_nr; i++)
> >> +                     if (S_ISGITLINK(active_cache[i]->ce_mode))
> >> +                             return 1;
> >> +     }
> >> +
> >> +     return 0;
> >> +}
> >
> > It may be a good idea to rearrange these by order to correctness.
> 
> I arranged by estimated speed, i.e. from fastest to slowest:
> * The first check just returns a value from memory in the standard case
>   Though the first one may take a hit in performance for the very first time
>   as it may need to load the config.
> * The next two are an actual stat system call, each having a different
>   'defect'. (We may have non-absorbed submodules or non-bare repos)
>   -> We could have a check for in-tree as well, not sure if that is desired.

Fair enough, I'm fine with the ordering then.

> 
> > Correctness may not be the best way to describe it, but which is the
> > strongest indicator that there is a submodule or that a repo 'has a
> > submodule'.
> 
> These indicators differ in strength for different scenarios IMO.
> (Just after clone: check for a .gitmodules file instead of a config;
> later: rather check for a config as it is fastest and actually catches
> active submodules; maybe we do not care about inactive submodules)

This is why I went back on my thinking :)  I realized that it really
depends on the scenario you are in.

> 
> >  That way in the future we could have a #define that is
> > SUBMODULE_CHECK_ANY or ALL or something....Now that I'm thinking harder
> > about that we may not want that, and just require explicitly stating
> > which check you want done.
> >
> > Anyways good looking patch, and I like the idea of consolidating the
> > checks into a single function.
> 
> Thanks,
> Stefan

-- 
Brandon Williams

^ permalink raw reply	[flat|threaded] 9+ messages in thread

* Re: [PATCH 2/2] clone: remember references for submodules even when not recursing
  2017-04-20 22:12   ` Brandon Williams
@ 2017-04-20 22:28     ` Stefan Beller
  0 siblings, 0 replies; 9+ messages in thread
From: Stefan Beller @ 2017-04-20 22:28 UTC (permalink / raw)
  To: Brandon Williams; +Cc: Maxime Viargues, git

On Thu, Apr 20, 2017 at 3:12 PM, Brandon Williams <bmwill@google.com> wrote:
> On 04/11, Stefan Beller wrote:
>> The commit 31224cbdc7 (clone: recursive and reference option triggers
>> submodule alternates, 2016-08-17) argued for any further `submodule update`
>> to respect the initial setup. This is not the case if you only pass
>> '--reference[-if-able]' to the initial clone without instructing to
>> recurse into submodules.
>>
>> If there are submodules however the user is likely to later run
>> a 'submodule update --init' to obtain the submodules. In this case we
>> also want to have the references available.
>>
>
> So the idea is to keep the references around even if the user doesn't
> want to recurse immediately?

Yes. This patch is a bug fix response for
https://public-inbox.org/git/35343b75-0aa7-3477-888b-3af5024ae7dd@serato.com/

Note that this breaks the test suite
t7407-submodule-foreach.sh
  15: test "update --recursive" with a flag with spaces
because the reference is recorded but not all submodules can
be referenced; the nested submodules are not populated.

A couple of thoughts on that
* A test for "update --recursive" ought to live in a test other than
  t7407-submodule-foreach.sh (Maybe in t7406-submodule-update.sh?)
* The test checks for white space issues in path names and the breakage
  shows an unintentional side effect of --reference: it may error out in
  more cases (not all submodules populated -> error)
* Maybe "git submodule update" should learn the --reference-if-able
  flag, just like git-clone did, to improve the submodule situation?
  (I put it on my todo list)

Thanks,
Stefan

^ permalink raw reply	[flat|threaded] 9+ messages in thread

end of thread, back to index

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-11 19:46 [PATCH 0/2] clone: record submodule alternates when not recursing Stefan Beller
2017-04-11 19:46 ` [PATCH 1/2] submodule.c: add has_submodules to check if we have any submodules Stefan Beller
2017-04-20 22:07   ` Brandon Williams
2017-04-20 22:20     ` Stefan Beller
2017-04-20 22:25       ` Brandon Williams
2017-04-11 19:46 ` [PATCH 2/2] clone: remember references for submodules even when not recursing Stefan Beller
2017-04-20 22:12   ` Brandon Williams
2017-04-20 22:28     ` Stefan Beller
2017-04-19 19:52 ` [PATCH 0/2] clone: record submodule alternates " Stefan Beller

git@vger.kernel.org mailing list mirror (one of many)

Archives are clonable:
	git clone --mirror https://public-inbox.org/git
	git clone --mirror http://ou63pmih66umazou.onion/git
	git clone --mirror http://czquwvybam4bgbro.onion/git
	git clone --mirror http://hjrcffqmbrq6wope.onion/git

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.version-control.git
	nntp://ou63pmih66umazou.onion/inbox.comp.version-control.git
	nntp://czquwvybam4bgbro.onion/inbox.comp.version-control.git
	nntp://hjrcffqmbrq6wope.onion/inbox.comp.version-control.git
	nntp://news.gmane.org/gmane.comp.version-control.git

 note: .onion URLs require Tor: https://www.torproject.org/
       or Tor2web: https://www.tor2web.org/

AGPL code for this site: git clone https://public-inbox.org/ public-inbox