Git development
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Paulius Zaleckas <paulius.zaleckas@gmail.com>
Cc: git@vger.kernel.org, "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
	"Glen Choo" <glencbz@gmail.com>, "Patrick Steinhardt" <ps@pks.im>
Subject: Re: [PATCH v4 2/2] fetch: add fetch.submoduleErrors to make submodule fetch errors non-fatal
Date: Tue, 14 Jul 2026 10:14:14 -0700	[thread overview]
Message-ID: <xmqq1pd5trx5.fsf@gitster.g> (raw)
In-Reply-To: <20260714132959.3368867-3-paulius.zaleckas@gmail.com> (Paulius Zaleckas's message of "Tue, 14 Jul 2026 16:29:57 +0300")

Paulius Zaleckas <paulius.zaleckas@gmail.com> writes:

> +	if (!strcmp(k, "fetch.submoduleerrors")) {
> +		if (!v)
> +			return config_error_nonbool(k);
> +		else if (!strcasecmp(v, "fail"))
> +			fetch_config->submodule_errors = SUBMODULE_ERRORS_FAIL;
> +		else if (!strcasecmp(v, "warn"))
> +			fetch_config->submodule_errors = SUBMODULE_ERRORS_WARN;
> +		else
> +			die(_("invalid value for '%s': '%s'"),
> +			    "fetch.submoduleErrors", v);
> +		return 0;
> +	}

Two points.

 * Do not use strcasecmp() on the value.

   While "fetch.submoduleerrors" may be case-insenstive, the value
   does not have to be.  We do not want to encourage users to write
   "[fetch] submoduleErrors = Fail", as some people may want to
   write third-party add-on scripts that parse "git config --get
   fetch.submoduleerrors" output.  For example:

	error_handling=$(git config --get fetch.submoduleErrors)
	case "$error_handling" in
	fail)
		... do something ... ;;
	warn)
		... do something else ... ;;
	esac

   We should not force them to write extra code to handle the value
   case-insensitively.

 * Since you need to convert between the enum and the string here,
   in option_parse_submodule_errors(), and in add_options_to_argv(),
   defining a pair of parse/format functions would be cleaner.

	/* really private - use accessors to parse and format */
	static const char *submodule_errors_[] = {
        	[SUBMODULE_ERRORS_FAIL] = "fail",
        	[SUBMODULE_ERRORS_WARN] = "warn",
	};

	static const char *submodule_error(int num)
	{
		assert(0 <= num && num < ARRAY_SIZE(submodule_errors_));
		return submodule_errors[num];
	}

	static int parse_submodule_error(const char *name)
	{
		for (int num = 0; num <	ARRAY_SIZE(submodule_errors_); num++)
			if (!strcmp(submodule_errors_[num], name))
				return num;
		return -1;
	}

The configuration parsing block would then become:

	if (!strcmp(k, "fetch.submoduleerrors")) {
		int num;

		if (!v)
			return config_error_nonbool(k);
		num = parse_submodule_error(v);
		if (num < 0)
			die(_("invalid value..."), ...);
		fetch_config->submodule_errors = num;
		return 0;
	}

This approach is much more maintainable.  You only need to keep the
submodule_errors_[] array up to date with respect to the error-handling
preprocessor macros.  Some reviewers might suggest converting these macros
into a proper enum.  I would not object to that change, but I would not
bother doing it myself as I do not personally care much about the
distinction between an enum and a preprocessor macro in this context.

> @@ -2205,6 +2219,10 @@ static void add_options_to_argv(struct strvec *argv,
>  		strvec_push(argv, "--no-recurse-submodules");
>  	else if (config->recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)
>  		strvec_push(argv, "--recurse-submodules=on-demand");
> +	if (config->submodule_errors == SUBMODULE_ERRORS_FAIL)
> +		strvec_push(argv, "--submodule-errors=fail");
> +	else if (config->submodule_errors == SUBMODULE_ERRORS_WARN)
> +		strvec_push(argv, "--submodule-errors=warn");

This part then becomes:

	if (config->submodule_errors < 0)
		; /* nothing */
	else {
		const char *name = submodule_error(config->submodule_errors);
		strvec_push(argv, "--submodule-errors=%s", name);
	}

This is, again, much more miantainable.

> +static int option_parse_submodule_errors(const struct option *opt,
> +					  const char *arg, int unset)
> +{
> +	int *v = opt->value;
> +	if (unset || !strcasecmp(arg, "fail"))
> +		*v = SUBMODULE_ERRORS_FAIL;
> +	else if (!strcasecmp(arg, "warn"))
> +		*v = SUBMODULE_ERRORS_WARN;
> +	else
> +		die(_("invalid value for '%s': '%s'"), "--submodule-errors", arg);
> +	return 0;
> +}

Updating this function is left as an exercise ;-)

      parent reply	other threads:[~2026-07-14 17:14 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-10 12:26 [PATCH v3 0/2] fetch: make submodule fetch errors configurable Paulius Zaleckas
2026-07-10 12:26 ` [PATCH v3 1/2] submodule: fix premature failure in recursive submodule fetch Paulius Zaleckas
2026-07-10 12:26 ` [PATCH v3 2/2] fetch: add fetch.submoduleErrors to make submodule fetch errors non-fatal Paulius Zaleckas
2026-07-10 22:21   ` Junio C Hamano
2026-07-14 13:29     ` Paulius Zaleckas
2026-07-14 13:29 ` [PATCH v4 0/2] fetch: make submodule fetch errors configurable Paulius Zaleckas
2026-07-14 13:29   ` [PATCH v4 1/2] submodule: fix premature failure in recursive submodule fetch Paulius Zaleckas
2026-07-14 13:29   ` [PATCH v4 2/2] fetch: add fetch.submoduleErrors to make submodule fetch errors non-fatal Paulius Zaleckas
2026-07-14 15:34     ` Junio C Hamano
2026-07-14 17:14     ` Junio C Hamano [this message]

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=xmqq1pd5trx5.fsf@gitster.g \
    --to=gitster@pobox.com \
    --cc=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=glencbz@gmail.com \
    --cc=paulius.zaleckas@gmail.com \
    --cc=ps@pks.im \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox