On Mon, Nov 23, 2020 at 04:05:04PM +0000, Derrick Stolee via GitGitGadget wrote: > > > The 'git config' builtin takes a 'value_regex' parameter for several > actions. This can cause confusion when expecting exact value matches > instead of regex matches, especially when the input string contains glob > characters. While callers can escape the patterns themselves, it would > be more friendly to allow an argument to disable the pattern matching in > favor of an exact string match. > > Add a new '--fixed-value' option that does not currently change the > behavior. The implementation will follow for each appropriate action. > For now, check and test that --fixed-value will abort the command when > included with an incompatible action or without a 'value_regex' > argument. > > The name '--fixed-value' was chosen over something simpler like > '--fixed' because some commands allow regular expressions on the > key in addition to the value. > > Signed-off-by: Derrick Stolee <dstolee@xxxxxxxxxxxxx> > --- > Documentation/git-config.txt | 20 +++++++++++++------- > builtin/config.c | 26 ++++++++++++++++++++++++++ > t/t1300-config.sh | 23 +++++++++++++++++++++++ > 3 files changed, 62 insertions(+), 7 deletions(-) > > diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt > index 7573160f21..d4bb928ea7 100644 > --- a/builtin/config.c > +++ b/builtin/config.c > @@ -34,6 +34,7 @@ static int respect_includes_opt = -1; > static struct config_options config_options; > static int show_origin; > static int show_scope; > +static int fixed_value; > > #define ACTION_GET (1<<0) > #define ACTION_GET_ALL (1<<1) > @@ -141,6 +142,7 @@ static struct option builtin_config_options[] = { > OPT_BIT(0, "rename-section", &actions, N_("rename section: old-name new-name"), ACTION_RENAME_SECTION), > OPT_BIT(0, "remove-section", &actions, N_("remove a section: name"), ACTION_REMOVE_SECTION), > OPT_BIT('l', "list", &actions, N_("list all"), ACTION_LIST), > + OPT_BOOL(0, "fixed-value", &fixed_value, N_("use string equality when matching values")), I'm not sure how to feel about this phrasing. I wonder if it would be clearer to say something like 'treat 'value_regex' as a literal string instead'? Hmmm. > + if (fixed_value) { > + int allowed_usage = 0; > + > + switch (actions) { > + case ACTION_GET: > + case ACTION_GET_ALL: > + case ACTION_GET_REGEXP: > + case ACTION_UNSET: > + case ACTION_UNSET_ALL: > + allowed_usage = argc > 1 && !!argv[1]; > + break; > + > + case ACTION_SET_ALL: > + case ACTION_REPLACE_ALL: > + allowed_usage = argc > 2 && !!argv[2]; > + break; > + } > + > + if (!allowed_usage) { > + error(_("--fixed-value only applies with 'value_regex'")); > + usage_builtin_config(); > + } > + } > + To me this really needs a comment. I think you are checking whether the value_regex is actually present, and the position of that regex changes depending on the rest of the arg list... What about something like: /* If set, ensure 'value_regex' was provided also */ if (fixed_value) { ... /* 'git config --unset-all <key> <value_regex>' */ case ACTION_UNSET_ALL: ... /* 'git config --replace-all <key> <new value> <value_regex>' */ case ACTION_REPLACE_ALL: ... > +test_expect_success 'refuse --fixed-value for incompatible actions' ' > + git config --file=config dev.null bogus && > + > + # These modes do not allow --fixed-value at all > + test_must_fail git config --file=config --fixed-value --add dev.null bogus && > + test_must_fail git config --file=config --fixed-value --get-urlmatch dev.null bogus && > + test_must_fail git config --file=config --fixed-value --get-urlmatch dev.null bogus && > + test_must_fail git config --file=config --fixed-value --rename-section dev null && > + test_must_fail git config --file=config --fixed-value --remove-section dev && > + test_must_fail git config --file=config --fixed-value --list && > + test_must_fail git config --file=config --fixed-value --get-color dev.null && > + test_must_fail git config --file=config --fixed-value --get-colorbool dev.null && > + > + # These modes complain when --fixed-value has no value_regex > + test_must_fail git config --file=config --fixed-value dev.null bogus && > + test_must_fail git config --file=config --fixed-value --replace-all dev.null bogus && > + test_must_fail git config --file=config --fixed-value --get dev.null && > + test_must_fail git config --file=config --fixed-value --get-all dev.null && > + test_must_fail git config --file=config --fixed-value --get-regexp "dev.*" && > + test_must_fail git config --file=config --fixed-value --unset dev.null && > + test_must_fail git config --file=config --fixed-value --unset-all dev.null > +' > + I'd expect to see a positive test as well, which you could later evolve into a test to ensure behavior. - Emily