Re: [BUG] `git clone '-c KEY=VALUE'` no longer works
- From
Johannes Schindelin <johannes.schindelin@gmx.de>
- Date
- Nov 25, 2025, 20:16 UTC
- Message-ID
- <bb7791ea-cfdb-842e-c079-b62b0f183fe1@gmx.de>
- In-Reply-To
- <CALnO6CBJppT3ELyu54rJvP+uqcMomJS9Nr_JTgfssn8iqG7MWA@mail.gmail.com>
Hi Ran & Ben,
On Mon, 24 Nov 2025, D. Ben Knoble wrote:
Show 35 quoted lines
> On Mon, Nov 24, 2025 at 12:23 AM Ran Ari-Gur <ran.arigur+git@samsara.com> wrote: > > > > There's a small regression in Git v2.52.0; it used to be that a command of the > > form > > > > git clone '-c KEY=VALUE' ... > > > > or > > > > git clone '--config= KEY=VALUE' ... > > > > would trim whitespace around KEY, making the command equivalent to this: > > > > git clone --config=KEY=VALUE ... > > > > The relevant code was here: > > https://github.com/git/git/blob/v2.51.2/config.c#L649 > > > > That functionality was removed in this refactoring commit: > > https://github.com/git/git/commit/dcecac2580ef871186fdc4e9efc87815a4ce4c66 > > > > As a result, a command like the above will now fail, with an error such as this: > > > > error: invalid key: advice.detachedHead=false > > fatal: unable to write parameters to config file > > > > because config keys are not allowed to contain whitespace. > > > > I believe this change was unintentional; it was not mentioned in the commit > > message or the release notes. > > > > This probably isn't a common case, and the project where I ran into this issue > > has already fixed it on their end (they now pass -c and KEY=VALUE as separate > > arguments); but since Git aims to ensure backward-compatibility where possible, > > I figured I should report it.
This has also been reported in https://github.com/git-for-windows/git/issues/5972 as breaking Git LFS.
Show 13 quoted lines
> Thanks! As far as backward compatibility, I think this behavior has > been around since 2010's 8b1fa77867 (Allow passing of configuration > parameters in the command line, 2010-03-26) which morphed via > 572e4f6a0c (Use strbufs instead of open-coded string manipulation, > 2010-03-26) into the strbuf_trim(pair[0]) that you pointed to as > disappearing. > > Interestingly, I note that we dropped the trim around pair[1] in > 06eb708f33 (config: always parse GIT_CONFIG_PARAMETERS during > git_config, 2011-05-24), but I don't see that discussed in the commit > message either. I tried a handful of mailing list searches around > 20110524224955.GC24527@sigill.intra.peff.net, but didn't find any > relevant discussion (though my lore-search skills are mediocre).
I am awfully pinched on time right now, but I _think_ that this could be the start of a fix:
-- snipsnap --
diff --git a/config.c b/config.c index f1def0dcfba..2b2efe479dc 100644 --- a/config.c +++ b/config.c @@ -637,7 +637,7 @@ int git_config_parse_parameter(const char *text, kvi_from_param(&kvi); - string_list_split(&pair, text, "=", 1); + string_list_split_f(&pair, text, "=", 1, STRING_LIST_SPLIT_TRIM_FIRST); if (!pair.nr) return error(_("bogus config parameter: %s"), text); diff --git a/string-list.c b/string-list.c index 08dc00984cc..9b5f1d71a9d 100644 --- a/string-list.c +++ b/string-list.c @@ -326,6 +326,13 @@ static int split_string(struct string_list *list, const char *string, const char else if (!in_place && !list->strdup_strings) BUG("string_list_split() called without strdup_strings"); + if (flags & STRING_LIST_SPLIT_TRIM_FIRST) { + if (flags & STRING_LIST_SPLIT_TRIM) + flags &= ~STRING_LIST_SPLIT_TRIM_FIRST; + else + flags |= STRING_LIST_SPLIT_TRIM; + } + for (;;) { char *end; @@ -345,6 +352,9 @@ static int split_string(struct string_list *list, const char *string, const char if (!end) return count; p = end + 1; + + if (flags & STRING_LIST_SPLIT_TRIM_FIRST) + flags &= ~STRING_LIST_SPLIT_TRIM; } } diff --git a/string-list.h b/string-list.h index fa6ba07853c..938707bf09a 100644 --- a/string-list.h +++ b/string-list.h @@ -297,6 +297,8 @@ enum { STRING_LIST_SPLIT_TRIM = (1 << 0), /* omit adding empty string piece to the resulting list */ STRING_LIST_SPLIT_NONEMPTY = (1 << 1), + /* trim only the first */ + STRING_LIST_SPLIT_TRIM_FIRST = (1 << 2), }; int string_list_split_f(struct string_list *, const char *string,