diff mbox series

[2/2] submodule--helper: advise on fatal alternate error

Message ID 26c3b388a24eef7f03eb423c10e21430bc3f019e.1574731649.git.jonathantanmy@google.com (mailing list archive)
State New, archived
Headers show
Series Advice upon clone --recurse-submodules --reference | expand

Commit Message

Jonathan Tan Nov. 26, 2019, 1:31 a.m. UTC
When recursively cloning a superproject with some shallow modules
defined in its .gitmodules, then recloning with "--reference=<path>", an
error occurs. For example:

  git clone --recurse-submodules --branch=master -j8 \
    https://android.googlesource.com/platform/superproject \
    master
  git clone --recurse-submodules --branch=master -j8 \
    https://android.googlesource.com/platform/superproject \
    --reference master master2

fails with:

  fatal: submodule '<snip>' cannot add alternate: reference repository
  '<snip>' is shallow

When a alternate computed from the superproject's alternate cannot be
added, whether in this case or another, advise about configuring the
"submodule.alternateErrorStrategy" configuration option and using
"--reference-if-able" instead of "--reference" when cloning.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
---
 Documentation/config/advice.txt |  3 +++
 advice.c                        |  2 ++
 advice.h                        |  1 +
 builtin/submodule--helper.c     | 10 ++++++++++
 4 files changed, 16 insertions(+)

Comments

Jeff King Nov. 27, 2019, 11:49 a.m. UTC | #1
On Mon, Nov 25, 2019 at 05:31:00PM -0800, Jonathan Tan wrote:

> When recursively cloning a superproject with some shallow modules
> defined in its .gitmodules, then recloning with "--reference=<path>", an
> error occurs. For example:
> 
>   git clone --recurse-submodules --branch=master -j8 \
>     https://android.googlesource.com/platform/superproject \
>     master
>   git clone --recurse-submodules --branch=master -j8 \
>     https://android.googlesource.com/platform/superproject \
>     --reference master master2
> 
> fails with:
> 
>   fatal: submodule '<snip>' cannot add alternate: reference repository
>   '<snip>' is shallow
> 
> When a alternate computed from the superproject's alternate cannot be
> added, whether in this case or another, advise about configuring the
> "submodule.alternateErrorStrategy" configuration option and using
> "--reference-if-able" instead of "--reference" when cloning.

It sounds like that advice sends people in the right direction, which is
a good thing.

I kind of wonder if the default for alternateErrorStrategy should be
more lenient, but I don't really know much about the feature in the
first place. I'll let people who are more clueful ponder that, but
certainly your patch is an improvement in the meantime.

One minor suggestion:

> +static void advise_submodule_alternate_error_die(void)
> +{
> +	if (!advice_submodule_alternate_error_strategy_die)
> +		return;
> +	advise(_("An alternate computed from a superproject's alternate is invalid."));
> +	advise(_("To allow Git to clone without an alternate in such a case, set submodule.alternateErrorStrategy to 'info' or, equivalently, clone with '--reference-if-able' instead of '--reference'."));
> +}

The advise() function handles newlines gracefully (putting a "hint:" at
the start of each line). So you can put both in a single call, and wrap
the second long line, which also lets translators see the whole message
as a unit. Many of the existing calls define the message outside of any
function (e.g., embedded_advice), which makes it easier to see how long
the lines will be when displayed.

So maybe:

  static const alternate_error_advice[] = N_(
  "An alternate computed from a superproject's alternate is invalid.\n"
  "To allow Git to clone without an alternate in such a case, set\n"
  "submodule.alternateErrorStrategy to 'info' or, equivalently, clone with\n"
  "'--reference-if-able' instead of '--reference'."
  );

  ...
	switch (sas->error_mode) {
	case SUBMODULE_ALTERNATE_ERROR_DIE:
		if (advice_submodule_alternate_error_strategy_die)
			advise(_(alternate_error_advice));
		die(...);

?

-Peff
diff mbox series

Patch

diff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt
index 6aaa360202..d4e698cd3f 100644
--- a/Documentation/config/advice.txt
+++ b/Documentation/config/advice.txt
@@ -107,4 +107,7 @@  advice.*::
 		editor input from the user.
 	nestedTag::
 		Advice shown if a user attempts to recursively tag a tag object.
+	submoduleAlternateErrorStrategyDie:
+		Advice shown when a submodule.alternateErrorStrategy option
+		configured to "die" causes a fatal error.
 --
diff --git a/advice.c b/advice.c
index 3ee0ee2d8f..249c60dcf3 100644
--- a/advice.c
+++ b/advice.c
@@ -30,6 +30,7 @@  int advice_waiting_for_editor = 1;
 int advice_graft_file_deprecated = 1;
 int advice_checkout_ambiguous_remote_branch_name = 1;
 int advice_nested_tag = 1;
+int advice_submodule_alternate_error_strategy_die = 1;
 
 static int advice_use_color = -1;
 static char advice_colors[][COLOR_MAXLEN] = {
@@ -89,6 +90,7 @@  static struct {
 	{ "graftFileDeprecated", &advice_graft_file_deprecated },
 	{ "checkoutAmbiguousRemoteBranchName", &advice_checkout_ambiguous_remote_branch_name },
 	{ "nestedTag", &advice_nested_tag },
+	{ "submoduleAlternateErrorStrategyDie", &advice_submodule_alternate_error_strategy_die },
 
 	/* make this an alias for backward compatibility */
 	{ "pushNonFastForward", &advice_push_update_rejected }
diff --git a/advice.h b/advice.h
index d015404843..b706780614 100644
--- a/advice.h
+++ b/advice.h
@@ -30,6 +30,7 @@  extern int advice_waiting_for_editor;
 extern int advice_graft_file_deprecated;
 extern int advice_checkout_ambiguous_remote_branch_name;
 extern int advice_nested_tag;
+extern int advice_submodule_alternate_error_strategy_die;
 
 int git_default_advice_config(const char *var, const char *value);
 __attribute__((format (printf, 1, 2)))
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 2c2395a620..bdfc46fdea 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -19,6 +19,7 @@ 
 #include "diffcore.h"
 #include "diff.h"
 #include "object-store.h"
+#include "advice.h"
 
 #define OPT_QUIET (1 << 0)
 #define OPT_CACHED (1 << 1)
@@ -1268,6 +1269,14 @@  struct submodule_alternate_setup {
 #define SUBMODULE_ALTERNATE_SETUP_INIT { NULL, \
 	SUBMODULE_ALTERNATE_ERROR_IGNORE, NULL }
 
+static void advise_submodule_alternate_error_die(void)
+{
+	if (!advice_submodule_alternate_error_strategy_die)
+		return;
+	advise(_("An alternate computed from a superproject's alternate is invalid."));
+	advise(_("To allow Git to clone without an alternate in such a case, set submodule.alternateErrorStrategy to 'info' or, equivalently, clone with '--reference-if-able' instead of '--reference'."));
+}
+
 static int add_possible_reference_from_superproject(
 		struct object_directory *odb, void *sas_cb)
 {
@@ -1299,6 +1308,7 @@  static int add_possible_reference_from_superproject(
 		} else {
 			switch (sas->error_mode) {
 			case SUBMODULE_ALTERNATE_ERROR_DIE:
+				advise_submodule_alternate_error_die();
 				die(_("submodule '%s' cannot add alternate: %s"),
 				    sas->submodule_name, err.buf);
 			case SUBMODULE_ALTERNATE_ERROR_INFO: