Re: Inconsistent/buggy behaviour of "git config --add"
From: Junio C Hamano <hidden>
Date: 2024-03-23 17:52:53
Tim Landscheidt [off-list ref] writes:
| # git config section.key value0 | # git config --add section.key value1
The action verb --add comes immediately after "git config" (and possibly file-option and type option), so this is a request to append "key = value1" in the "[section]" (if there is no existing section.key, then "[section]" would have to be created at the same time, but in this case there already is one).
| # cat .git/config | [core] | repositoryformatversion = 0 | filemode = true | bare = false | logallrefupdates = true | [section] | key = value0 | key = value1
So this makes perfect sense.
| # git config section.key --add value2
No action verb immediately after "git config" (possibly after
file-option and type option). This should be taken as
git config <name> <value> <value-pattern>
where
<name> = section.key
<value> = --add
<value-pattern> = value2
As we lack --replace-all, the default behaviour is to replace a
single existing entry of "section.key" with existing value "value2",
with the new value "--add", or if there is no such existing entry,
add one such entry.
| # cat .git/config | [core] | repositoryformatversion = 0 | filemode = true | bare = false | logallrefupdates = true | [section] | key = value0 | key = value1 | key = --add
which seems to be what the code did.
| # git config section.key --add
No action verb immediately after "git config" (possibly after
file-option and type option). This should be taken as
git config <name> <value>
where
<name> = section.key
<value> = --add
and is an attempt to replace existing section.key with the new value
"--add", but because we have already three such entries, we get
| warning: section.key has multiple values | error: cannot overwrite multiple values with a single value | Use a regexp, --add or --replace-all to change section.key. | #
which sounds sensible.
So on one hand, "--add" must be given before the key to add a line, but if on the other hand one passes the option after the key and before the value, it is literally taken as the value and the value does not seem to be interpreted as a value-pattern, either. However, if the value is missing, Git correctly recognizes that this does not make sense.
Not really. I agree that the "git config" syntax is messy, but I followed your example with "git config --help" (especially its SYNOPSIS section) in hand, and reached the above explanation, which your conjecutre does not quite match.
My expectation of least surprise is that "git config section.key --add value" should be equivalent to "git config --add section.key value".
You cannot have "--add" as a value by doing so.
If that is not possible, I would expect "git config section.key --add value2" to mean "change the values of section.key to '--add' where they currently match the value-pattern of 'value2'".
I think your expectation needs to be updated in this particular case, but there is a discussion to revamp the UI started elsewhere, which stops the double-dashed action verbs and instead trigger different actions as subcommands of "git config", which will hopefully make things easier to understand.