builtin/config: introduce "set" subcommand

Introduce a new "set" subcommand to git-config(1). Please refer to
preceding commits regarding the motivation behind this change.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Patrick Steinhardt 2024-05-06 10:56:33 +02:00 committed by Junio C Hamano
parent 4e51389000
commit 00bbdde141
3 changed files with 140 additions and 63 deletions

View File

@ -11,9 +11,7 @@ SYNOPSIS
[verse] [verse]
'git config list' [<file-option>] [<display-option>] [--includes] 'git config list' [<file-option>] [<display-option>] [--includes]
'git config get' [<file-option>] [<display-option>] [--includes] [--all] [--regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] <name> 'git config get' [<file-option>] [<display-option>] [--includes] [--all] [--regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] <name>
'git config' [<file-option>] [--type=<type>] [--comment=<message>] [--fixed-value] [--show-origin] [--show-scope] [-z|--null] <name> [<value> [<value-pattern>]] 'git config set' [<file-option>] [--type=<type>] [--comment=<message>] [--all] [--value=<value>] [--fixed-value] <name> <value>
'git config' [<file-option>] [--type=<type>] [--comment=<message>] --add <name> <value>
'git config' [<file-option>] [--type=<type>] [--comment=<message>] [--fixed-value] --replace-all <name> <value> [<value-pattern>]
'git config' [<file-option>] [--fixed-value] --unset <name> [<value-pattern>] 'git config' [<file-option>] [--fixed-value] --unset <name> [<value-pattern>]
'git config' [<file-option>] [--fixed-value] --unset-all <name> [<value-pattern>] 'git config' [<file-option>] [--fixed-value] --unset-all <name> [<value-pattern>]
'git config' [<file-option>] --rename-section <old-name> <new-name> 'git config' [<file-option>] --rename-section <old-name> <new-name>
@ -27,7 +25,7 @@ You can query/set/replace/unset options with this command. The name is
actually the section and the key separated by a dot, and the value will be actually the section and the key separated by a dot, and the value will be
escaped. escaped.


Multiple lines can be added to an option by using the `--add` option. Multiple lines can be added to an option by using the `--append` option.
If you want to update or unset an option which can occur on multiple If you want to update or unset an option which can occur on multiple
lines, a `value-pattern` (which is an extended regular expression, lines, a `value-pattern` (which is an extended regular expression,
unless the `--fixed-value` option is given) needs to be given. Only the unless the `--fixed-value` option is given) needs to be given. Only the
@ -82,6 +80,13 @@ get::
emits all values associated with key. Returns error code 1 if key is emits all values associated with key. Returns error code 1 if key is
not present. not present.


set::
Set value for one or more config options. By default, this command
refuses to write multi-valued config options. Passing `--all` will
replace all multi-valued config options with the new value, whereas
`--value=` will replace all config options whose values match the given
pattern.

[[OPTIONS]] [[OPTIONS]]
OPTIONS OPTIONS
------- -------
@ -90,10 +95,9 @@ OPTIONS
Default behavior is to replace at most one line. This replaces Default behavior is to replace at most one line. This replaces
all lines matching the key (and optionally the `value-pattern`). all lines matching the key (and optionally the `value-pattern`).


--add:: --append::
Adds a new line to the option without altering any existing Adds a new line to the option without altering any existing
values. This is the same as providing '^$' as the `value-pattern` values. This is the same as providing '--value=^$' in `set`.
in `--replace-all`.


--comment <message>:: --comment <message>::
Append a comment at the end of new or modified lines. Append a comment at the end of new or modified lines.
@ -296,6 +300,9 @@ recommended to migrate to the new syntax.
'git config <name>':: 'git config <name>'::
Replaced by `git config get <name>`. Replaced by `git config get <name>`.


'git config <name> <value> [<value-pattern>]'::
Replaced by `git config set [--value=<pattern>] <name> <value>`.

-l:: -l::
--list:: --list::
Replaced by `git config list`. Replaced by `git config list`.
@ -315,6 +322,9 @@ recommended to migrate to the new syntax.
--get-color <name> [<default>]:: --get-color <name> [<default>]::
Replaced by `git config get --type=color [--default=<default>] <name>`. Replaced by `git config get --type=color [--default=<default>] <name>`.


--add <name> <value>::
Replaced by `git config set --append <name> <value>`.

CONFIGURATION CONFIGURATION
------------- -------------
`pager.config` is only respected when listing configuration, i.e., when `pager.config` is only respected when listing configuration, i.e., when
@ -361,7 +371,7 @@ precedence over values read earlier. When multiple values are taken then all
values of a key from all files will be used. values of a key from all files will be used.


By default, options are only written to the repository specific By default, options are only written to the repository specific
configuration file. Note that this also affects options like `--replace-all` configuration file. Note that this also affects options like `set`
and `--unset`. *'git config' will only ever change one file at a time*. and `--unset`. *'git config' will only ever change one file at a time*.


You can limit which configuration sources are read from or written to by You can limit which configuration sources are read from or written to by
@ -497,7 +507,7 @@ Given a .git/config like this:
you can set the filemode to true with you can set the filemode to true with


------------ ------------
% git config core.filemode true % git config set core.filemode true
------------ ------------


The hypothetical proxy command entries actually have a postfix to discern The hypothetical proxy command entries actually have a postfix to discern
@ -505,7 +515,7 @@ what URL they apply to. Here is how to change the entry for kernel.org
to "ssh". to "ssh".


------------ ------------
% git config core.gitproxy '"ssh" for kernel.org' 'for kernel.org$' % git config set --value='for kernel.org$' core.gitproxy '"ssh" for kernel.org'
------------ ------------


This makes sure that only the key/value pair for kernel.org is replaced. This makes sure that only the key/value pair for kernel.org is replaced.
@ -541,26 +551,26 @@ If you like to live dangerously, you can replace *all* core.gitproxy by a
new one with new one with


------------ ------------
% git config --replace-all core.gitproxy ssh % git config set --all core.gitproxy ssh
------------ ------------


However, if you really only want to replace the line for the default proxy, However, if you really only want to replace the line for the default proxy,
i.e. the one without a "for ..." postfix, do something like this: i.e. the one without a "for ..." postfix, do something like this:


------------ ------------
% git config core.gitproxy ssh '! for ' % git config set --value='! for ' core.gitproxy ssh
------------ ------------


To actually match only values with an exclamation mark, you have to To actually match only values with an exclamation mark, you have to


------------ ------------
% git config section.key value '[!]' % git config set --value='[!]' section.key value
------------ ------------


To add a new proxy, without altering any of the existing ones, use To add a new proxy, without altering any of the existing ones, use


------------ ------------
% git config --add core.gitproxy '"proxy-command" for example.com' % git config set --append core.gitproxy '"proxy-command" for example.com'
------------ ------------


An example to use customized color from the configuration in your An example to use customized color from the configuration in your

View File

@ -18,6 +18,7 @@
static const char *const builtin_config_usage[] = { static const char *const builtin_config_usage[] = {
N_("git config list [<file-option>] [<display-option>] [--includes]"), N_("git config list [<file-option>] [<display-option>] [--includes]"),
N_("git config get [<file-option>] [<display-option>] [--includes] [--all] [--regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] <name>"), N_("git config get [<file-option>] [<display-option>] [--includes] [--all] [--regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] <name>"),
N_("git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
NULL NULL
}; };


@ -31,6 +32,11 @@ static const char *const builtin_config_get_usage[] = {
NULL NULL
}; };


static const char *const builtin_config_set_usage[] = {
N_("git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
NULL
};

static char *key; static char *key;
static regex_t *key_regexp; static regex_t *key_regexp;
static const char *value_pattern; static const char *value_pattern;
@ -849,9 +855,66 @@ static int cmd_config_get(int argc, const char **argv, const char *prefix)
return get_value(argv[0], value_pattern, flags); return get_value(argv[0], value_pattern, flags);
} }


static int cmd_config_set(int argc, const char **argv, const char *prefix)
{
const char *value_pattern = NULL, *comment_arg = NULL;
char *comment = NULL;
int flags = 0, append = 0;
struct option opts[] = {
CONFIG_LOCATION_OPTIONS,
CONFIG_TYPE_OPTIONS,
OPT_GROUP(N_("Filter")),
OPT_BIT(0, "all", &flags, N_("replace multi-valued config option with new value"), CONFIG_FLAGS_MULTI_REPLACE),
OPT_STRING(0, "value", &value_pattern, N_("pattern"), N_("show config with values matching the pattern")),
OPT_BIT(0, "fixed-value", &flags, N_("use string equality when comparing values to value pattern"), CONFIG_FLAGS_FIXED_VALUE),
OPT_GROUP(N_("Other")),
OPT_STRING(0, "comment", &comment_arg, N_("value"), N_("human-readable comment string (# will be prepended as needed)")),
OPT_BOOL(0, "append", &append, N_("add a new line without altering any existing values")),
OPT_END(),
};
struct key_value_info default_kvi = KVI_INIT;
char *value;
int ret;

argc = parse_options(argc, argv, prefix, opts, builtin_config_set_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
check_write();
check_argc(argc, 2, 2);

if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern)
die(_("--fixed-value only applies with --value=<pattern>"));
if (append && value_pattern)
die(_("--append cannot be used with --value=<pattern>"));
if (append)
value_pattern = CONFIG_REGEX_NONE;

comment = git_config_prepare_comment_string(comment_arg);

handle_config_location(prefix);

value = normalize_value(argv[0], argv[1], &default_kvi);

if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern) {
ret = git_config_set_multivar_in_file_gently(given_config_source.file,
argv[0], value, value_pattern,
comment, flags);
} else {
ret = git_config_set_in_file_gently(given_config_source.file,
argv[0], comment, value);
if (ret == CONFIG_NOTHING_SET)
error(_("cannot overwrite multiple values with a single value\n"
" Use a regexp, --add or --replace-all to change %s."), argv[0]);
}

free(comment);
free(value);
return ret;
}

static struct option builtin_subcommand_options[] = { static struct option builtin_subcommand_options[] = {
OPT_SUBCOMMAND("list", &subcommand, cmd_config_list), OPT_SUBCOMMAND("list", &subcommand, cmd_config_list),
OPT_SUBCOMMAND("get", &subcommand, cmd_config_get), OPT_SUBCOMMAND("get", &subcommand, cmd_config_get),
OPT_SUBCOMMAND("set", &subcommand, cmd_config_set),
OPT_END(), OPT_END(),
}; };



View File

@ -20,12 +20,16 @@ legacy)
mode_get="" mode_get=""
mode_get_all="--get-all" mode_get_all="--get-all"
mode_get_regexp="--get-regexp" mode_get_regexp="--get-regexp"
mode_set=""
mode_replace_all="--replace-all"
;; ;;
subcommands) subcommands)
mode_prefix="" mode_prefix=""
mode_get="get" mode_get="get"
mode_get_all="get --all" mode_get_all="get --all"
mode_get_regexp="get --regexp --all --show-names" mode_get_regexp="get --regexp --all --show-names"
mode_set="set"
mode_replace_all="set --all"
;; ;;
*) *)
BUG "unknown mode $mode";; BUG "unknown mode $mode";;
@ -132,7 +136,7 @@ cat > expect << EOF
penguin = little blue penguin = little blue
EOF EOF
test_expect_success 'initial' ' test_expect_success 'initial' '
git config section.penguin "little blue" && git config ${mode_set} section.penguin "little blue" &&
test_cmp expect .git/config test_cmp expect .git/config
' '


@ -142,7 +146,7 @@ cat > expect << EOF
Movie = BadPhysics Movie = BadPhysics
EOF EOF
test_expect_success 'mixed case' ' test_expect_success 'mixed case' '
git config Section.Movie BadPhysics && git config ${mode_set} Section.Movie BadPhysics &&
test_cmp expect .git/config test_cmp expect .git/config
' '


@ -154,7 +158,7 @@ cat > expect << EOF
WhatEver = Second WhatEver = Second
EOF EOF
test_expect_success 'similar section' ' test_expect_success 'similar section' '
git config Sections.WhatEver Second && git config ${mode_set} Sections.WhatEver Second &&
test_cmp expect .git/config test_cmp expect .git/config
' '


@ -167,7 +171,7 @@ cat > expect << EOF
WhatEver = Second WhatEver = Second
EOF EOF
test_expect_success 'uppercase section' ' test_expect_success 'uppercase section' '
git config SECTION.UPPERCASE true && git config ${mode_set} SECTION.UPPERCASE true &&
test_cmp expect .git/config test_cmp expect .git/config
' '


@ -194,8 +198,8 @@ EOF


test_expect_success 'append comments' ' test_expect_success 'append comments' '
git config --replace-all --comment="Pygoscelis papua" section.penguin gentoo && git config --replace-all --comment="Pygoscelis papua" section.penguin gentoo &&
git config --comment="find fish" section.disposition peckish && git config ${mode_set} --comment="find fish" section.disposition peckish &&
git config --comment="#abc" section.foo bar && git config ${mode_set} --comment="#abc" section.foo bar &&


git config --comment="and comment" section.spsp value && git config --comment="and comment" section.spsp value &&
git config --comment=" # and comment" section.htsp value && git config --comment=" # and comment" section.htsp value &&
@ -204,7 +208,7 @@ test_expect_success 'append comments' '
' '


test_expect_success 'Prohibited LF in comment' ' test_expect_success 'Prohibited LF in comment' '
test_must_fail git config --comment="a${LF}b" section.k v test_must_fail git config ${mode_set} --comment="a${LF}b" section.k v
' '


test_expect_success 'non-match result' 'test_cmp expect .git/config' test_expect_success 'non-match result' 'test_cmp expect .git/config'
@ -301,14 +305,14 @@ test_expect_success 'multiple unset is correct' '
cp .git/config2 .git/config cp .git/config2 .git/config


test_expect_success '--replace-all missing value' ' test_expect_success '--replace-all missing value' '
test_must_fail git config --replace-all beta.haha && test_must_fail git config ${mode_replace_all} beta.haha &&
test_cmp .git/config2 .git/config test_cmp .git/config2 .git/config
' '


rm .git/config2 rm .git/config2


test_expect_success '--replace-all' ' test_expect_success '--replace-all' '
git config --replace-all beta.haha gamma git config ${mode_replace_all} beta.haha gamma
' '


cat > expect << EOF cat > expect << EOF
@ -335,7 +339,7 @@ noIndent= sillyValue ; 'nother silly comment
[nextSection] noNewline = ouch [nextSection] noNewline = ouch
EOF EOF
test_expect_success 'really mean test' ' test_expect_success 'really mean test' '
git config beta.haha alpha && git config ${mode_set} beta.haha alpha &&
test_cmp expect .git/config test_cmp expect .git/config
' '


@ -350,7 +354,7 @@ noIndent= sillyValue ; 'nother silly comment
nonewline = wow nonewline = wow
EOF EOF
test_expect_success 'really really mean test' ' test_expect_success 'really really mean test' '
git config nextsection.nonewline wow && git config ${mode_set} nextsection.nonewline wow &&
test_cmp expect .git/config test_cmp expect .git/config
' '


@ -824,16 +828,16 @@ EOF


test_expect_success 'section ending' ' test_expect_success 'section ending' '
rm -f .git/config && rm -f .git/config &&
git config gitcvs.enabled true && git config ${mode_set} gitcvs.enabled true &&
git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite && git config ${mode_set} gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite &&
git config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite && git config ${mode_set} gitcvs.dbname %Ggitcvs2.%a.%m.sqlite &&
test_cmp expect .git/config test_cmp expect .git/config


' '


test_expect_success numbers ' test_expect_success numbers '
git config kilo.gram 1k && git config ${mode_set} kilo.gram 1k &&
git config mega.ton 1m && git config ${mode_set} mega.ton 1m &&
echo 1024 >expect && echo 1024 >expect &&
echo 1048576 >>expect && echo 1048576 >>expect &&
git config --int --get kilo.gram >actual && git config --int --get kilo.gram >actual &&
@ -842,20 +846,20 @@ test_expect_success numbers '
' '


test_expect_success '--int is at least 64 bits' ' test_expect_success '--int is at least 64 bits' '
git config giga.watts 121g && git config ${mode_set} giga.watts 121g &&
echo >expect && echo >expect &&
test_cmp_config 129922760704 --int --get giga.watts test_cmp_config 129922760704 --int --get giga.watts
' '


test_expect_success 'invalid unit' ' test_expect_success 'invalid unit' '
git config aninvalid.unit "1auto" && git config ${mode_set} aninvalid.unit "1auto" &&
test_cmp_config 1auto aninvalid.unit && test_cmp_config 1auto aninvalid.unit &&
test_must_fail git config --int --get aninvalid.unit 2>actual && test_must_fail git config --int --get aninvalid.unit 2>actual &&
test_grep "bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit" actual test_grep "bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit" actual
' '


test_expect_success 'invalid unit boolean' ' test_expect_success 'invalid unit boolean' '
git config commit.gpgsign "1true" && git config ${mode_set} commit.gpgsign "1true" &&
test_cmp_config 1true commit.gpgsign && test_cmp_config 1true commit.gpgsign &&
test_must_fail git config --bool --get commit.gpgsign 2>actual && test_must_fail git config --bool --get commit.gpgsign 2>actual &&
test_grep "bad boolean config value .1true. for .commit.gpgsign." actual test_grep "bad boolean config value .1true. for .commit.gpgsign." actual
@ -885,14 +889,14 @@ EOF


test_expect_success bool ' test_expect_success bool '


git config bool.true1 01 && git config ${mode_set} bool.true1 01 &&
git config bool.true2 -1 && git config ${mode_set} bool.true2 -1 &&
git config bool.true3 YeS && git config ${mode_set} bool.true3 YeS &&
git config bool.true4 true && git config ${mode_set} bool.true4 true &&
git config bool.false1 000 && git config ${mode_set} bool.false1 000 &&
git config bool.false2 "" && git config ${mode_set} bool.false2 "" &&
git config bool.false3 nO && git config ${mode_set} bool.false3 nO &&
git config bool.false4 FALSE && git config ${mode_set} bool.false4 FALSE &&
rm -f result && rm -f result &&
for i in 1 2 3 4 for i in 1 2 3 4
do do
@ -903,7 +907,7 @@ test_expect_success bool '


test_expect_success 'invalid bool (--get)' ' test_expect_success 'invalid bool (--get)' '


git config bool.nobool foobar && git config ${mode_set} bool.nobool foobar &&
test_must_fail git config --bool --get bool.nobool' test_must_fail git config --bool --get bool.nobool'


test_expect_success 'invalid bool (set)' ' test_expect_success 'invalid bool (set)' '
@ -1092,7 +1096,7 @@ test_expect_success 'get --expiry-date' '


test_expect_success 'get --type=color' ' test_expect_success 'get --type=color' '
rm .git/config && rm .git/config &&
git config foo.color "red" && git config ${mode_set} foo.color "red" &&
git config --get --type=color foo.color >actual.raw && git config --get --type=color foo.color >actual.raw &&
test_decode_color <actual.raw >actual && test_decode_color <actual.raw >actual &&
echo "<RED>" >expect && echo "<RED>" >expect &&
@ -1129,10 +1133,10 @@ cat > expect << EOF
EOF EOF
test_expect_success 'quoting' ' test_expect_success 'quoting' '
rm -f .git/config && rm -f .git/config &&
git config quote.leading " test" && git config ${mode_set} quote.leading " test" &&
git config quote.ending "test " && git config ${mode_set} quote.ending "test " &&
git config quote.semicolon "test;test" && git config ${mode_set} quote.semicolon "test;test" &&
git config quote.hash "test#test" && git config ${mode_set} quote.hash "test#test" &&
test_cmp expect .git/config test_cmp expect .git/config
' '


@ -1140,7 +1144,7 @@ test_expect_success 'key with newline' '
test_must_fail git config ${mode_get} "key.with test_must_fail git config ${mode_get} "key.with
newline" 123' newline" 123'


test_expect_success 'value with newline' 'git config key.sub value.with\\\ test_expect_success 'value with newline' 'git config ${mode_set} key.sub value.with\\\
newline' newline'


cat > .git/config <<\EOF cat > .git/config <<\EOF
@ -1199,21 +1203,21 @@ test_expect_success '--null --get-regexp' '


test_expect_success 'inner whitespace kept verbatim, spaces only' ' test_expect_success 'inner whitespace kept verbatim, spaces only' '
echo "foo bar" >expect && echo "foo bar" >expect &&
git config section.val "foo bar" && git config ${mode_set} section.val "foo bar" &&
git config ${mode_get} section.val >actual && git config ${mode_get} section.val >actual &&
test_cmp expect actual test_cmp expect actual
' '


test_expect_success 'inner whitespace kept verbatim, horizontal tabs only' ' test_expect_success 'inner whitespace kept verbatim, horizontal tabs only' '
echo "fooQQbar" | q_to_tab >expect && echo "fooQQbar" | q_to_tab >expect &&
git config section.val "$(cat expect)" && git config ${mode_set} section.val "$(cat expect)" &&
git config ${mode_get} section.val >actual && git config ${mode_get} section.val >actual &&
test_cmp expect actual test_cmp expect actual
' '


test_expect_success 'inner whitespace kept verbatim, horizontal tabs and spaces' ' test_expect_success 'inner whitespace kept verbatim, horizontal tabs and spaces' '
echo "foo Q bar" | q_to_tab >expect && echo "foo Q bar" | q_to_tab >expect &&
git config section.val "$(cat expect)" && git config ${mode_set} section.val "$(cat expect)" &&
git config ${mode_get} section.val >actual && git config ${mode_get} section.val >actual &&
test_cmp expect actual test_cmp expect actual
' '
@ -1252,12 +1256,12 @@ test_expect_success 'check split_cmdline return' '
git init repo && git init repo &&
( (
cd repo && cd repo &&
git config alias.split-cmdline-fix "echo \"" && git config ${mode_set} alias.split-cmdline-fix "echo \"" &&
test_must_fail git split-cmdline-fix && test_must_fail git split-cmdline-fix &&
echo foo >foo && echo foo >foo &&
git add foo && git add foo &&
git commit -m "initial commit" && git commit -m "initial commit" &&
git config branch.main.mergeoptions "echo \"" && git config ${mode_set} branch.main.mergeoptions "echo \"" &&
test_must_fail git merge main test_must_fail git merge main
) )
' '
@ -1295,12 +1299,12 @@ test_expect_success 'key sanity-checking' '
test_must_fail git config ${mode_get} foo.1bar && test_must_fail git config ${mode_get} foo.1bar &&
test_must_fail git config ${mode_get} foo."ba test_must_fail git config ${mode_get} foo."ba
z".bar && z".bar &&
test_must_fail git config . false && test_must_fail git config ${mode_set} . false &&
test_must_fail git config .foo false && test_must_fail git config ${mode_set} .foo false &&
test_must_fail git config foo. false && test_must_fail git config ${mode_set} foo. false &&
test_must_fail git config .foo. false && test_must_fail git config ${mode_set} .foo. false &&
git config foo.bar true && git config ${mode_set} foo.bar true &&
git config foo."ba =z".bar false git config ${mode_set} foo."ba =z".bar false
' '


test_expect_success 'git -c works with aliases of builtins' ' test_expect_success 'git -c works with aliases of builtins' '
@ -2523,7 +2527,7 @@ test_expect_success '--replace-all does not invent newlines' '
[abc] [abc]
Qkey = b Qkey = b
EOF EOF
git config --replace-all abc.key b && git config ${mode_replace_all} abc.key b &&
test_cmp expect .git/config test_cmp expect .git/config
' '


@ -2595,8 +2599,8 @@ test_expect_success 'refuse --fixed-value for incompatible actions' '
test_must_fail git config --file=config --fixed-value --get-colorbool dev.null && test_must_fail git config --file=config --fixed-value --get-colorbool dev.null &&


# These modes complain when --fixed-value has no value-pattern # These modes complain when --fixed-value has no value-pattern
test_must_fail git config --file=config --fixed-value dev.null bogus && test_must_fail git config ${mode_set} --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 ${mode_replace_all} --file=config --fixed-value dev.null bogus &&
test_must_fail git config ${mode_prefix}get --file=config --fixed-value dev.null && test_must_fail git config ${mode_prefix}get --file=config --fixed-value dev.null &&
test_must_fail git config ${mode_get_all} --file=config --fixed-value dev.null && test_must_fail git config ${mode_get_all} --file=config --fixed-value dev.null &&
test_must_fail git config ${mode_get_regexp} --file=config --fixed-value "dev.*" && test_must_fail git config ${mode_get_regexp} --file=config --fixed-value "dev.*" &&
@ -2637,7 +2641,7 @@ test_expect_success '--fixed-value uses exact string matching' '
test_must_fail git config ${mode_get} --file=config fixed.test && test_must_fail git config ${mode_get} --file=config fixed.test &&


cp initial config && cp initial config &&
git config --file=config --replace-all fixed.test bogus "$META" && git config --file=config fixed.test bogus "$META" &&
git config ${mode_prefix}list --file=config >actual && git config ${mode_prefix}list --file=config >actual &&
cat >expect <<-EOF && cat >expect <<-EOF &&
fixed.test=$META fixed.test=$META