Patrick Steinhardt <ps@xxxxxx> writes: > While git-config(1) has several modes, those modes are not exposed with > subcommands but instead by specifying e.g. `--unset` or `--list`. This s/specifying/specifying flags/ perhaps? > user interface is not really in line with how our more modern commands > work, where it is a lot more customary to say e.g. `git remote list`. Tangent: I totally agree with the patch, but it would be nice to have a 'DesigningCommands' document which would highlight UX do's and don'ts. It would be nice to add that as reference in discussions. > Furthermore, to add to the confusion, git-config(1) also allows the user > to request modes implicitly by just specifying the correct number of > arguments. Thus, `git config foo.bar` will retrieve the value of > "foo.bar" while `git config foo.bar baz` will set it to "baz". > > Overall, this makes for a confusing interface that could really use a > makeover. It hurts discoverability of what you can do with git-config(1) > and is comparatively easy to get wrong. Converting the command to have > subcommands instead would go a long way to help address these issues. > > One concern in this context is backwards compatibility. Luckily, we can > introduce subcommands without breaking backwards compatibility at all. > This is because all the implicit modes of git-config(1) require that the > first argument is a properly formatted config key. And as config keys > _must_ have a dot in their name, any value without a dot would have been > discarded by git-config(1) previous to this change. Thus, given that > none of the subcommands do have a dot, they are unambiguous. > > Introduce the first such new subcommand, which is "git config list". To > retain backwards compatibility we only conditionally use subcommands and > will fall back to the old syntax in case no subcommand was detected. > This should help to transition to the new-style syntax until we > eventually deprecate and remove the old-style syntax. > > Note that the way we handle this we're duplicating some functionality > across old and new syntax. While this isn't pretty, it helps us to > ensure that there really is no change in behaviour for the old syntax. > > Amend tests such that we run them both with old and new style syntax. > As tests are now run twice, state from the first run may be still be > around in the second run and thus cause tests to fail. Add cleanup logic > as required to fix such tests. > > Signed-off-by: Patrick Steinhardt <ps@xxxxxx> > --- > Documentation/git-config.txt | 26 ++++++--- > builtin/config.c | 90 ++++++++++++++++++++++++---- > t/t1300-config.sh | 110 +++++++++++++++++++++-------------- > 3 files changed, 162 insertions(+), 64 deletions(-) > > diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt > index ac61113fcc..c83c97cb7e 100644 > --- a/Documentation/git-config.txt > +++ b/Documentation/git-config.txt > @@ -9,6 +9,7 @@ git-config - Get and set repository or global options > SYNOPSIS > -------- > [verse] > +'git config list' [<file-option>] [<display-option>] [--includes] > 'git config' [<file-option>] [--type=<type>] [--comment=<message>] [--fixed-value] [--show-origin] [--show-scope] [-z|--null] <name> [<value> [<value-pattern>]] > '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>] > @@ -20,7 +21,6 @@ SYNOPSIS > '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>] --remove-section <name> > -'git config' [<file-option>] [--show-origin] [--show-scope] [-z|--null] [--name-only] -l | --list > 'git config' [<file-option>] --get-color <name> [<default>] > 'git config' [<file-option>] --get-colorbool <name> [<stdout-is-tty>] > 'git config' [<file-option>] -e | --edit > @@ -74,6 +74,12 @@ On success, the command returns the exit code 0. > A list of all available configuration variables can be obtained using the > `git help --config` command. > > +COMMANDS > +-------- > + > +list:: > + List all variables set in config file, along with their values. > + > [[OPTIONS]] > OPTIONS > ------- > @@ -190,10 +196,6 @@ See also <<FILES>>. > --unset-all:: > Remove all lines matching the key from config file. > > --l:: > ---list:: > - List all variables set in config file, along with their values. > - > --fixed-value:: > When used with the `value-pattern` argument, treat `value-pattern` as > an exact string instead of a regular expression. This will restrict > @@ -248,7 +250,7 @@ Valid `<type>`'s include: > contain line breaks. > > --name-only:: > - Output only the names of config variables for `--list` or > + Output only the names of config variables for `list` or > `--get-regexp`. > > --show-origin:: > @@ -300,10 +302,20 @@ Valid `<type>`'s include: > When using `--get`, and the requested variable is not found, behave as if > <value> were the value assigned to that variable. > > +DEPRECATED MODES > +---------------- > + > +The following modes have been deprecated in favor of subcommands. It is > +recommended to migrate to the new syntax. > + > +-l:: > +--list:: > + Replaced by `git config list`. > + > CONFIGURATION > ------------- > `pager.config` is only respected when listing configuration, i.e., when > -using `--list` or any of the `--get-*` which may return multiple results. > +using `list` or any of the `--get-*` which may return multiple results. > The default is to use a pager. > > [[FILES]] > diff --git a/builtin/config.c b/builtin/config.c > index 59877065f8..f89ddce8da 100644 > --- a/builtin/config.c > +++ b/builtin/config.c > @@ -16,10 +16,16 @@ > #include "worktree.h" > > static const char *const builtin_config_usage[] = { > + N_("git config list [<file-option>] [<display-option>] [--includes]"), > N_("git config [<options>]"), > NULL > }; > > +static const char *const builtin_config_list_usage[] = { > + N_("git config list [<file-option>] [<display-option>] [--includes]"), > + NULL > +}; > + > static char *key; > static regex_t *key_regexp; > static const char *value_pattern; > @@ -33,6 +39,7 @@ static char delim = '='; > static char key_delim = ' '; > static char term = '\n'; > > +static parse_opt_subcommand_fn *subcommand; > static int use_global_config, use_system_config, use_local_config; > static int use_worktree_config; > static struct git_config_source given_config_source; > @@ -706,14 +713,24 @@ static void handle_nul(void) { > } > } > > +#define CONFIG_LOCATION_OPTIONS \ > + OPT_GROUP(N_("Config file location")), \ > + OPT_BOOL(0, "global", &use_global_config, N_("use global config file")), \ > + OPT_BOOL(0, "system", &use_system_config, N_("use system config file")), \ > + OPT_BOOL(0, "local", &use_local_config, N_("use repository config file")), \ > + OPT_BOOL(0, "worktree", &use_worktree_config, N_("use per-worktree config file")), \ > + OPT_STRING('f', "file", &given_config_source.file, N_("file"), N_("use given config file")), \ > + OPT_STRING(0, "blob", &given_config_source.blob, N_("blob-id"), N_("read config from given blob object")) > + > +#define CONFIG_DISPLAY_OPTIONS \ > + OPT_GROUP(N_("Display options")), \ > + OPT_BOOL('z', "null", &end_nul, N_("terminate values with NUL byte")), \ > + OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")), \ > + OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")), \ > + OPT_BOOL(0, "show-scope", &show_scope, N_("show scope of config (worktree, local, global, system, command)")) > + > static struct option builtin_config_options[] = { > - OPT_GROUP(N_("Config file location")), > - OPT_BOOL(0, "global", &use_global_config, N_("use global config file")), > - OPT_BOOL(0, "system", &use_system_config, N_("use system config file")), > - OPT_BOOL(0, "local", &use_local_config, N_("use repository config file")), > - OPT_BOOL(0, "worktree", &use_worktree_config, N_("use per-worktree config file")), > - OPT_STRING('f', "file", &given_config_source.file, N_("file"), N_("use given config file")), > - OPT_STRING(0, "blob", &given_config_source.blob, N_("blob-id"), N_("read config from given blob object")), > + CONFIG_LOCATION_OPTIONS, > OPT_GROUP(N_("Action")), > OPT_CMDMODE(0, "get", &actions, N_("get value: name [<value-pattern>]"), ACTION_GET), > OPT_CMDMODE(0, "get-all", &actions, N_("get all values: key [<value-pattern>]"), ACTION_GET_ALL), > @@ -737,15 +754,12 @@ static struct option builtin_config_options[] = { > OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR), > OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH), > OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE), > + CONFIG_DISPLAY_OPTIONS, > OPT_GROUP(N_("Other")), > - OPT_BOOL('z', "null", &end_nul, N_("terminate values with NUL byte")), > - OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")), > - OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")), > - OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")), > - OPT_BOOL(0, "show-scope", &show_scope, N_("show scope of config (worktree, local, global, system, command)")), > OPT_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")), > OPT_STRING(0, "comment", &comment_arg, N_("value"), N_("human-readable comment string (# will be prepended as needed)")), > OPT_BOOL(0, "fixed-value", &fixed_value, N_("use string equality when comparing values to 'value-pattern'")), > + OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")), > OPT_END(), > }; > > @@ -754,6 +768,42 @@ static NORETURN void usage_builtin_config(void) > usage_with_options(builtin_config_usage, builtin_config_options); > } > > +static int cmd_config_list(int argc, const char **argv, const char *prefix) > +{ > + struct option opts[] = { > + CONFIG_LOCATION_OPTIONS, > + CONFIG_DISPLAY_OPTIONS, > + OPT_GROUP(N_("Other")), > + OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")), > + OPT_END(), > + }; > + > + argc = parse_options(argc, argv, prefix, opts, builtin_config_list_usage, 0); > + check_argc(argc, 0, 0); > + > + handle_config_location(prefix); > + handle_nul(); > + > + setup_auto_pager("config", 1); > + > + if (config_with_options(show_all_config, NULL, > + &given_config_source, the_repository, > + &config_options) < 0) { > + if (given_config_source.file) > + die_errno(_("unable to read config file '%s'"), > + given_config_source.file); > + else > + die(_("error processing config file(s)")); > + } > + > + return 0; > +} > + > +static struct option builtin_subcommand_options[] = { > + OPT_SUBCOMMAND("list", &subcommand, cmd_config_list), > + OPT_END(), > +}; > + > int cmd_config(int argc, const char **argv, const char *prefix) > { > char *value = NULL, *comment = NULL; > @@ -763,6 +813,22 @@ int cmd_config(int argc, const char **argv, const char *prefix) > > given_config_source.file = xstrdup_or_null(getenv(CONFIG_ENVIRONMENT)); > > + /* > + * This is somewhat hacky: we first parse the command line while > + * keeping all args intact in order to determine whether a subcommand > + * has been specified. If so, we re-parse it a second time, but this > + * time we drop KEEP_ARGV0. This is so that we don't munge the command > + * line in case no subcommand was given, which would otherwise confuse > + * us when parsing the legacy-style modes that don't use subcommands. > + */ > + argc = parse_options(argc, argv, prefix, builtin_subcommand_options, builtin_config_usage, > + PARSE_OPT_SUBCOMMAND_OPTIONAL|PARSE_OPT_NO_INTERNAL_HELP|PARSE_OPT_KEEP_ARGV0|PARSE_OPT_KEEP_UNKNOWN_OPT); > + if (subcommand) { > + argc = parse_options(argc, argv, prefix, builtin_subcommand_options, builtin_config_usage, > + PARSE_OPT_SUBCOMMAND_OPTIONAL|PARSE_OPT_NO_INTERNAL_HELP|PARSE_OPT_KEEP_UNKNOWN_OPT); > + return subcommand(argc, argv, prefix); > + } > + > argc = parse_options(argc, argv, prefix, builtin_config_options, > builtin_config_usage, > PARSE_OPT_STOP_AT_NON_OPTION); > diff --git a/t/t1300-config.sh b/t/t1300-config.sh > index 86dc70769a..f77d2f7847 100755 > --- a/t/t1300-config.sh > +++ b/t/t1300-config.sh > @@ -11,6 +11,20 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME > TEST_PASSES_SANITIZE_LEAK=true > . ./test-lib.sh > > +for mode in legacy subcommands > +do > + > +case "$mode" in > +legacy) > + mode_prefix="--" > + ;; > +subcommands) > + mode_prefix="" > + ;; > +*) > + BUG "unknown mode $mode";; > +esac > + > test_expect_success 'setup whitespace config' ' > sed -e "s/^|//" \ > -e "s/[$]$//" \ > @@ -460,11 +474,11 @@ version.1.2.3eX.alpha=beta > EOF > > test_expect_success 'working --list' ' > - git config --list > output && > + git config ${mode_prefix}list > output && > test_cmp expect output > ' > test_expect_success '--list without repo produces empty output' ' > - git --git-dir=nonexistent config --list >output && > + git --git-dir=nonexistent config ${mode_prefix}list >output && > test_must_be_empty output > ' > > @@ -476,7 +490,7 @@ version.1.2.3eX.alpha > EOF > > test_expect_success '--name-only --list' ' > - git config --name-only --list >output && > + git config ${mode_prefix}list --name-only >output && > test_cmp expect output > ' > > @@ -614,17 +628,17 @@ ein.bahn=strasse > EOF > > test_expect_success 'alternative GIT_CONFIG' ' > - GIT_CONFIG=other-config git config --list >output && > + GIT_CONFIG=other-config git config ${mode_prefix}list >output && > test_cmp expect output > ' > > test_expect_success 'alternative GIT_CONFIG (--file)' ' > - git config --file other-config --list >output && > + git config ${mode_prefix}list --file other-config >output && > test_cmp expect output > ' > > test_expect_success 'alternative GIT_CONFIG (--file=-)' ' > - git config --file - --list <other-config >output && > + git config ${mode_prefix}list --file - <other-config >output && > test_cmp expect output > ' > > @@ -637,6 +651,7 @@ test_expect_success 'editing stdin is an error' ' > ' > > test_expect_success 'refer config from subdirectory' ' > + test_when_finished "rm -r x" && > mkdir x && > test_cmp_config -C x strasse --file=../other-config --get ein.bahn > ' > @@ -847,7 +862,7 @@ test_expect_success 'line number is reported correctly' ' > ' > > test_expect_success 'invalid stdin config' ' > - echo "[broken" | test_must_fail git config --list --file - >output 2>&1 && > + echo "[broken" | test_must_fail git config ${mode_prefix}list --file - >output 2>&1 && > test_grep "bad config line 1 in standard input" output > ' > > @@ -1139,7 +1154,7 @@ section.quotecont=cont;inued > EOF > > test_expect_success 'value continued on next line' ' > - git config --list > result && > + git config ${mode_prefix}list > result && > test_cmp expect result > ' > > @@ -1163,7 +1178,7 @@ Qsection.sub=section.val4 > Qsection.sub=section.val5Q > EOF > test_expect_success '--null --list' ' > - git config --null --list >result.raw && > + git config ${mode_prefix}list --null >result.raw && > nul_to_q <result.raw >result && > echo >>result && > test_cmp expect result > @@ -1198,6 +1213,7 @@ test_expect_success 'inner whitespace kept verbatim, horizontal tabs and spaces' > ' > > test_expect_success SYMLINKS 'symlinked configuration' ' > + test_when_finished "rm myconfig" && > ln -s notyet myconfig && > git config --file=myconfig test.frotz nitfol && > test -h myconfig && > @@ -1218,10 +1234,11 @@ test_expect_success SYMLINKS 'symlinked configuration' ' > ' > > test_expect_success SYMLINKS 'symlink to nonexistent configuration' ' > + test_when_finished "rm linktonada linktolinktonada" && > ln -s doesnotexist linktonada && > ln -s linktonada linktolinktonada && > - test_must_fail git config --file=linktonada --list && > - test_must_fail git config --file=linktolinktonada --list > + test_must_fail git config ${mode_prefix}list --file=linktonada && > + test_must_fail git config ${mode_prefix}list --file=linktolinktonada > ' > > test_expect_success 'check split_cmdline return' ' > @@ -1478,7 +1495,7 @@ do > done > > test_expect_success 'git -c is not confused by empty environment' ' > - GIT_CONFIG_PARAMETERS="" git -c x.one=1 config --list > + GIT_CONFIG_PARAMETERS="" git -c x.one=1 config ${mode_prefix}list > ' > > test_expect_success 'GIT_CONFIG_PARAMETERS handles old-style entries' ' > @@ -1669,31 +1686,31 @@ test_expect_success 'git config ignores pairs with empty count' ' > ' > > test_expect_success 'git config fails with invalid count' ' > - test_must_fail env GIT_CONFIG_COUNT=10a git config --list 2>error && > + test_must_fail env GIT_CONFIG_COUNT=10a git config ${mode_prefix}list 2>error && > test_grep "bogus count" error && > - test_must_fail env GIT_CONFIG_COUNT=9999999999999999 git config --list 2>error && > + test_must_fail env GIT_CONFIG_COUNT=9999999999999999 git config ${mode_prefix}list 2>error && > test_grep "too many entries" error > ' > > test_expect_success 'git config fails with missing config key' ' > test_must_fail env GIT_CONFIG_COUNT=1 GIT_CONFIG_VALUE_0="value" \ > - git config --list 2>error && > + git config ${mode_prefix}list 2>error && > test_grep "missing config key" error > ' > > test_expect_success 'git config fails with missing config value' ' > test_must_fail env GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0="pair.one" \ > - git config --list 2>error && > + git config ${mode_prefix}list 2>error && > test_grep "missing config value" error > ' > > test_expect_success 'git config fails with invalid config pair key' ' > test_must_fail env GIT_CONFIG_COUNT=1 \ > GIT_CONFIG_KEY_0= GIT_CONFIG_VALUE_0=value \ > - git config --list && > + git config ${mode_prefix}list && > test_must_fail env GIT_CONFIG_COUNT=1 \ > GIT_CONFIG_KEY_0=missing-section GIT_CONFIG_VALUE_0=value \ > - git config --list > + git config ${mode_prefix}list > ' > > test_expect_success 'environment overrides config file' ' > @@ -1733,7 +1750,7 @@ test_expect_success 'git config --edit works' ' > git config -f tmp test.value no && > echo test.value=yes >expect && > GIT_EDITOR="echo [test]value=yes >" git config -f tmp --edit && > - git config -f tmp --list >actual && > + git config ${mode_prefix}list -f tmp >actual && > test_cmp expect actual > ' > > @@ -1742,7 +1759,7 @@ test_expect_success 'git config --edit respects core.editor' ' > echo test.value=yes >expect && > test_config core.editor "echo [test]value=yes >" && > git config -f tmp --edit && > - git config -f tmp --list >actual && > + git config ${mode_prefix}list -f tmp >actual && > test_cmp expect actual > ' > > @@ -2093,7 +2110,7 @@ test_expect_success '--show-origin with --list' ' > command line: user.cmdline=true > EOF > GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=user.environ GIT_CONFIG_VALUE_0=true\ > - git -c user.cmdline=true config --list --show-origin >output && > + git -c user.cmdline=true config ${mode_prefix}list --show-origin >output && > test_cmp expect output > ' > > @@ -2110,7 +2127,7 @@ test_expect_success '--show-origin with --list --null' ' > includeQcommand line:Quser.cmdline > trueQ > EOF > - git -c user.cmdline=true config --null --list --show-origin >output.raw && > + git -c user.cmdline=true config ${mode_prefix}list --null --show-origin >output.raw && > nul_to_q <output.raw >output && > # The here-doc above adds a newline that the --null output would not > # include. Add it here to make the two comparable. > @@ -2124,7 +2141,7 @@ test_expect_success '--show-origin with single file' ' > file:.git/config user.override=local > file:.git/config include.path=../include/relative.include > EOF > - git config --local --list --show-origin >output && > + git config ${mode_prefix}list --local --show-origin >output && > test_cmp expect output > ' > > @@ -2162,7 +2179,7 @@ test_expect_success !MINGW '--show-origin escape special file name characters' ' > cat >expect <<-\EOF && > file:"file\" (dq) and spaces.conf" user.custom=true > EOF > - git config --file "$WEIRDLY_NAMED_FILE" --show-origin --list >output && > + git config ${mode_prefix}list --file "$WEIRDLY_NAMED_FILE" --show-origin >output && > test_cmp expect output > ' > > @@ -2170,7 +2187,7 @@ test_expect_success '--show-origin stdin' ' > cat >expect <<-\EOF && > standard input: user.custom=true > EOF > - git config --file - --show-origin --list <"$CUSTOM_CONFIG_FILE" >output && > + git config ${mode_prefix}list --file - --show-origin <"$CUSTOM_CONFIG_FILE" >output && > test_cmp expect output > ' > > @@ -2197,7 +2214,7 @@ test_expect_success '--show-origin blob' ' > cat >expect <<-EOF && > blob:$blob user.custom=true > EOF > - git config --blob=$blob --show-origin --list >output && > + git config ${mode_prefix}list --blob=$blob --show-origin >output && > test_cmp expect output > ) > ' > @@ -2213,7 +2230,7 @@ test_expect_success '--show-origin blob ref' ' > cp "$CUSTOM_CONFIG_FILE" custom.conf && > git add custom.conf && > git commit -m "new config file" && > - git config --blob=main:custom.conf --show-origin --list >output && > + git config ${mode_prefix}list --blob=main:custom.conf --show-origin >output && > test_cmp expect output > ) > ' > @@ -2239,13 +2256,14 @@ test_expect_success '--show-scope with --list' ' > worktree user.worktree=true > command user.cmdline=true > EOF > + test_when_finished "git worktree remove wt1" && > git worktree add wt1 && > # We need these to test for worktree scope, but outside of this > # test, this is just noise > test_config core.repositoryformatversion 1 && > test_config extensions.worktreeConfig true && > git config --worktree user.worktree true && > - git -c user.cmdline=true config --list --show-scope >output && > + git -c user.cmdline=true config ${mode_prefix}list --show-scope >output && > test_cmp expect output > ' > > @@ -2254,7 +2272,7 @@ test_expect_success !MINGW '--show-scope with --blob' ' > cat >expect <<-EOF && > command user.custom=true > EOF > - git config --blob=$blob --show-scope --list >output && > + git config ${mode_prefix}list --blob=$blob --show-scope >output && > test_cmp expect output > ' > > @@ -2264,7 +2282,7 @@ test_expect_success '--show-scope with --local' ' > local user.override=local > local include.path=../include/relative.include > EOF > - git config --local --list --show-scope >output && > + git config ${mode_prefix}list --local --show-scope >output && > test_cmp expect output > ' > > @@ -2288,7 +2306,7 @@ test_expect_success '--show-scope with --show-origin' ' > local file:.git/../include/relative.include user.relative=include > command command line: user.cmdline=true > EOF > - git -c user.cmdline=true config --list --show-origin --show-scope >output && > + git -c user.cmdline=true config ${mode_prefix}list --show-origin --show-scope >output && > test_cmp expect output > ' > > @@ -2329,7 +2347,7 @@ test_expect_success 'override global and system config' ' > global home.config=true > local local.config=true > EOF > - git config --show-scope --list >output && > + git config ${mode_prefix}list --show-scope >output && > test_cmp expect output && > > cat >expect <<-EOF && > @@ -2338,20 +2356,20 @@ test_expect_success 'override global and system config' ' > local local.config=true > EOF > GIT_CONFIG_NOSYSTEM=false GIT_CONFIG_SYSTEM=custom-system-config GIT_CONFIG_GLOBAL=custom-global-config \ > - git config --show-scope --list >output && > + git config ${mode_prefix}list --show-scope >output && > test_cmp expect output && > > cat >expect <<-EOF && > local local.config=true > EOF > GIT_CONFIG_NOSYSTEM=false GIT_CONFIG_SYSTEM=/dev/null GIT_CONFIG_GLOBAL=/dev/null \ > - git config --show-scope --list >output && > + git config ${mode_prefix}list --show-scope >output && > test_cmp expect output > ' > > test_expect_success 'override global and system config with missing file' ' > - test_must_fail env GIT_CONFIG_GLOBAL=does-not-exist GIT_CONFIG_SYSTEM=/dev/null git config --global --list && > - test_must_fail env GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_SYSTEM=does-not-exist git config --system --list && > + test_must_fail env GIT_CONFIG_GLOBAL=does-not-exist GIT_CONFIG_SYSTEM=/dev/null git config ${mode_prefix}list --global && > + test_must_fail env GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_SYSTEM=does-not-exist git config ${mode_prefix}list --system && > GIT_CONFIG_GLOBAL=does-not-exist GIT_CONFIG_SYSTEM=does-not-exist git version > ' > > @@ -2478,7 +2496,7 @@ test_expect_success 'set all config with value-pattern' ' > # no match => add new entry > cp initial config && > git config --file=config abc.key two a+ && > - git config --file=config --list >actual && > + git config ${mode_prefix}list --file=config >actual && > cat >expect <<-\EOF && > abc.key=one > abc.key=two > @@ -2491,7 +2509,7 @@ test_expect_success 'set all config with value-pattern' ' > > # multiple values, no match => add > git config --file=config abc.key three a+ && > - git config --file=config --list >actual && > + git config ${mode_prefix}list --file=config >actual && > cat >expect <<-\EOF && > abc.key=one > abc.key=two > @@ -2501,7 +2519,7 @@ test_expect_success 'set all config with value-pattern' ' > > # single match => replace > git config --file=config abc.key four h+ && > - git config --file=config --list >actual && > + git config ${mode_prefix}list --file=config >actual && > cat >expect <<-\EOF && > abc.key=one > abc.key=two > @@ -2516,7 +2534,7 @@ test_expect_success '--replace-all and value-pattern' ' > git config --file=config --add abc.key two && > git config --file=config --add abc.key three && > git config --file=config --replace-all abc.key four "o+" && > - git config --file=config --list >actual && > + git config ${mode_prefix}list --file=config >actual && > cat >expect <<-\EOF && > abc.key=four > abc.key=three > @@ -2534,7 +2552,7 @@ test_expect_success 'refuse --fixed-value for incompatible actions' ' > 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 ${mode_prefix}list --file=config --fixed-value && > 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 && > > @@ -2555,7 +2573,7 @@ test_expect_success '--fixed-value uses exact string matching' ' > > cp initial config && > git config --file=config fixed.test bogus "$META" && > - git config --file=config --list >actual && > + git config ${mode_prefix}list --file=config >actual && > cat >expect <<-EOF && > fixed.test=$META > fixed.test=bogus > @@ -2564,7 +2582,7 @@ test_expect_success '--fixed-value uses exact string matching' ' > > cp initial config && > git config --file=config --fixed-value fixed.test bogus "$META" && > - git config --file=config --list >actual && > + git config ${mode_prefix}list --file=config >actual && > cat >expect <<-\EOF && > fixed.test=bogus > EOF > @@ -2582,7 +2600,7 @@ test_expect_success '--fixed-value uses exact string matching' ' > > cp initial config && > git config --file=config --replace-all fixed.test bogus "$META" && > - git config --file=config --list >actual && > + git config ${mode_prefix}list --file=config >actual && > cat >expect <<-EOF && > fixed.test=$META > fixed.test=bogus > @@ -2590,7 +2608,7 @@ test_expect_success '--fixed-value uses exact string matching' ' > test_cmp expect actual && > > git config --file=config --fixed-value --replace-all fixed.test bogus "$META" && > - git config --file=config --list >actual && > + git config ${mode_prefix}list --file=config >actual && > cat >expect <<-EOF && > fixed.test=bogus > fixed.test=bogus > @@ -2751,4 +2769,6 @@ test_expect_success 'specifying multiple modes causes failure' ' > test_cmp expect err > ' > > +done > + > Nit: Wouldn't it be better if the tests are indented here? That way you know it's part of a loop.
Attachment:
signature.asc
Description: PGP signature