public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
From: "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com,
	"brian m. carlson" <sandals@crustytoothpaste.net>,
	"Phillip Wood" <phillip.wood123@gmail.com>,
	"Kristoffer Haugsbakk" <kristofferhaugsbakk@fastmail.com>,
	"Jean-Noël Avila" <jn.avila@free.fr>,
	"Patrick Steinhardt" <ps@pks.im>,
	"Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com>,
	"Derrick Stolee" <stolee@gmail.com>,
	"Derrick Stolee" <stolee@gmail.com>
Subject: [PATCH v3 03/13] config: make 'git config list --type=<X>' work
Date: Mon, 23 Feb 2026 12:26:45 +0000	[thread overview]
Message-ID: <2b2a325b55a906cc8eba97f2020684f44c42bfc5.1771849615.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2044.v3.git.1771849615.gitgitgadget@gmail.com>

From: Derrick Stolee <stolee@gmail.com>

Previously, the --type=<X> argument to 'git config list' was ignored and
did nothing. Now, we add the use of format_config() to the
show_all_config() function so each key-value pair is attempted to be
parsed. This is our first use of the 'gently' parameter with a nonzero
value.

When listing multiple values, our initial settings for the output format
is different. Add a new init helper to specify the fact that keys should
be shown and also add the default delimiters as they were unset in some
cases.

Our intention is that if there is an error in parsing, then the row is
not output. This is necessary to avoid the caller needing to build their
own validator to understand the difference between valid, canonicalized
types and other raw string values. The raw values will always be
available to the user if they do not specify the --type=<X> option.

The current behavior is more complicated, including error messages on
bad parsing or potentially complete failure of the command.  We add
tests at this point that demonstrate the current behavior so we can
witness the fix in future changes that parse these values quietly and
gently.

This is a change in behavior! We are starting to respect an option that
was previously ignored, leading to potential user confusion. This is
probably still a good option, since the --type argument did not change
behavior at all previously, so users can get the behavior they expect by
removing the --type argument or adding the --no-type argument.

t1300-config.sh is updated with the current behavior of this formatting
logic to justify the upcoming refactoring of format_config() that will
incrementally fix some of these cases to be more user-friendly.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
---
 Documentation/git-config.adoc |  3 ++
 builtin/config.c              | 35 +++++++------
 t/t1300-config.sh             | 97 ++++++++++++++++++++++++++++++++++-
 3 files changed, 119 insertions(+), 16 deletions(-)

diff --git a/Documentation/git-config.adoc b/Documentation/git-config.adoc
index ac3b536a15..5300dd4c51 100644
--- a/Documentation/git-config.adoc
+++ b/Documentation/git-config.adoc
@@ -240,6 +240,9 @@ Valid `<type>`'s include:
   that the given value is canonicalize-able as an ANSI color, but it is written
   as-is.
 +
+If the command is in `list` mode, then the `--type <type>` argument will apply
+to each listed config value. If the value does not successfully parse in that
+format, then it will be omitted from the list.
 
 --bool::
 --int::
diff --git a/builtin/config.c b/builtin/config.c
index b4c4228311..4c4c791883 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -318,21 +318,12 @@ static int show_all_config(const char *key_, const char *value_,
 {
 	const struct config_display_options *opts = cb;
 	const struct key_value_info *kvi = ctx->kvi;
+	struct strbuf formatted = STRBUF_INIT;
 
-	if (opts->show_origin || opts->show_scope) {
-		struct strbuf buf = STRBUF_INIT;
-		if (opts->show_scope)
-			show_config_scope(opts, kvi, &buf);
-		if (opts->show_origin)
-			show_config_origin(opts, kvi, &buf);
-		/* Use fwrite as "buf" can contain \0's if "end_null" is set. */
-		fwrite(buf.buf, 1, buf.len, stdout);
-		strbuf_release(&buf);
-	}
-	if (!opts->omit_values && value_)
-		printf("%s%c%s%c", key_, opts->delim, value_, opts->term);
-	else
-		printf("%s%c", key_, opts->term);
+	if (format_config(opts, &formatted, key_, value_, kvi, 1) >= 0)
+		fwrite(formatted.buf, 1, formatted.len, stdout);
+
+	strbuf_release(&formatted);
 	return 0;
 }
 
@@ -872,6 +863,19 @@ static void display_options_init(struct config_display_options *opts)
 	}
 }
 
+static void display_options_init_list(struct config_display_options *opts)
+{
+	opts->show_keys = 1;
+
+	if (opts->end_nul) {
+		display_options_init(opts);
+	} else {
+		opts->term = '\n';
+		opts->delim = ' ';
+		opts->key_delim = '=';
+	}
+}
+
 static int cmd_config_list(int argc, const char **argv, const char *prefix,
 			   struct repository *repo UNUSED)
 {
@@ -890,7 +894,7 @@ static int cmd_config_list(int argc, const char **argv, const char *prefix,
 	check_argc(argc, 0, 0);
 
 	location_options_init(&location_opts, prefix);
-	display_options_init(&display_opts);
+	display_options_init_list(&display_opts);
 
 	setup_auto_pager("config", 1);
 
@@ -1321,6 +1325,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
 
 	if (actions == ACTION_LIST) {
 		check_argc(argc, 0, 0);
+		display_options_init_list(&display_opts);
 		if (config_with_options(show_all_config, &display_opts,
 					&location_opts.source, the_repository,
 					&location_opts.options) < 0) {
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index 9850fcd5b5..dc744c0bae 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -2459,9 +2459,15 @@ done
 
 cat >.git/config <<-\EOF &&
 [section]
-foo = true
+foo = True
 number = 10
 big = 1M
+path = ~/dir
+red = red
+blue = Blue
+date = Fri Jun 4 15:46:55 2010
+missing=:(optional)no-such-path
+exists=:(optional)expect
 EOF
 
 test_expect_success 'identical modern --type specifiers are allowed' '
@@ -2503,6 +2509,95 @@ test_expect_success 'unset type specifiers may be reset to conflicting ones' '
 	test_cmp_config 1048576 --type=bool --no-type --type=int section.big
 '
 
+test_expect_success 'list --type=int shows only canonicalizable int values' '
+	cat >expect <<-EOF &&
+	section.number=10
+	section.big=1048576
+	EOF
+
+	test_must_fail git config ${mode_prefix}list --type=int
+'
+
+test_expect_success 'list --type=bool shows only canonicalizable bool values' '
+	cat >expect <<-EOF &&
+	section.foo=true
+	section.number=true
+	section.big=true
+	EOF
+
+	test_must_fail git config ${mode_prefix}list --type=bool
+'
+
+test_expect_success 'list --type=bool-or-int shows only canonicalizable values' '
+	cat >expect <<-EOF &&
+	section.foo=true
+	section.number=10
+	section.big=1048576
+	EOF
+
+	test_must_fail git config ${mode_prefix}list --type=bool-or-int
+'
+
+test_expect_success 'list --type=path shows only canonicalizable path values' '
+	# TODO: handling of missing path is incorrect here.
+	cat >expect <<-EOF &&
+	section.foo=True
+	section.number=10
+	section.big=1M
+	section.path=$HOME/dir
+	section.red=red
+	section.blue=Blue
+	section.date=Fri Jun 4 15:46:55 2010
+	section.missing=section.exists=expect
+	EOF
+
+	git config ${mode_prefix}list --type=path >actual 2>err &&
+	test_cmp expect actual &&
+	test_must_be_empty err
+'
+
+test_expect_success 'list --type=expiry-date shows only canonicalizable dates' '
+	cat >expecterr <<-EOF &&
+	error: '\''True'\'' for '\''section.foo'\'' is not a valid timestamp
+	error: '\''~/dir'\'' for '\''section.path'\'' is not a valid timestamp
+	error: '\''red'\'' for '\''section.red'\'' is not a valid timestamp
+	error: '\''Blue'\'' for '\''section.blue'\'' is not a valid timestamp
+	error: '\'':(optional)no-such-path'\'' for '\''section.missing'\'' is not a valid timestamp
+	error: '\'':(optional)expect'\'' for '\''section.exists'\'' is not a valid timestamp
+	EOF
+
+	git config ${mode_prefix}list --type=expiry-date >actual 2>err &&
+
+	# section.number and section.big parse as relative dates that could
+	# have clock skew in their results.
+	test_grep section.big actual &&
+	test_grep section.number actual &&
+	test_grep "section.date=$(git config --type=expiry-date section.$key)" actual &&
+	test_cmp expecterr err
+'
+
+test_expect_success 'list --type=color shows only canonicalizable color values' '
+	cat >expect <<-EOF &&
+	section.number=<>
+	section.red=<RED>
+	section.blue=<BLUE>
+	EOF
+
+	cat >expecterr <<-EOF &&
+	error: invalid color value: True
+	error: invalid color value: 1M
+	error: invalid color value: ~/dir
+	error: invalid color value: Fri Jun 4 15:46:55 2010
+	error: invalid color value: :(optional)no-such-path
+	error: invalid color value: :(optional)expect
+	EOF
+
+	git config ${mode_prefix}list --type=color >actual.raw 2>err &&
+	test_decode_color <actual.raw >actual &&
+	test_cmp expect actual &&
+	test_cmp expecterr err
+'
+
 test_expect_success '--type rejects unknown specifiers' '
 	test_must_fail git config --type=nonsense section.foo 2>error &&
 	test_grep "unrecognized --type argument" error
-- 
gitgitgadget


  parent reply	other threads:[~2026-02-23 12:27 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-10  4:42 [PATCH 0/5] [RFC] Make 'git config list --type=' parse and filter types Derrick Stolee via GitGitGadget
2026-02-10  4:42 ` [PATCH 1/5] config: move show_all_config() Derrick Stolee via GitGitGadget
2026-02-10  4:42 ` [PATCH 2/5] parse: add git_parse_maybe_pathname() Derrick Stolee via GitGitGadget
2026-02-11 12:13   ` Patrick Steinhardt
2026-02-10  4:42 ` [PATCH 3/5] config: allow format_config() to filter Derrick Stolee via GitGitGadget
2026-02-10  5:04   ` Junio C Hamano
2026-02-10 18:12     ` Derrick Stolee
2026-02-10  4:42 ` [PATCH 4/5] config: create special init for list mode Derrick Stolee via GitGitGadget
2026-02-10  4:42 ` [PATCH 5/5] config: make 'git config list --type=<X>' work Derrick Stolee via GitGitGadget
2026-02-11 12:13   ` Patrick Steinhardt
2026-02-11 17:49     ` Derrick Stolee
2026-02-12  6:39       ` Patrick Steinhardt
2026-02-10  4:59 ` [PATCH 0/5] [RFC] Make 'git config list --type=' parse and filter types Junio C Hamano
2026-02-10 18:18   ` Derrick Stolee
2026-02-11 12:13 ` Patrick Steinhardt
2026-02-13 23:55 ` [PATCH v2 00/13] " Derrick Stolee via GitGitGadget
2026-02-13 23:55   ` [PATCH v2 01/13] config: move show_all_config() Derrick Stolee via GitGitGadget
2026-02-13 23:55   ` [PATCH v2 02/13] config: add 'gently' parameter to format_config() Derrick Stolee via GitGitGadget
2026-02-17  9:04     ` Patrick Steinhardt
2026-02-13 23:55   ` [PATCH v2 03/13] config: make 'git config list --type=<X>' work Derrick Stolee via GitGitGadget
2026-02-17  9:04     ` Patrick Steinhardt
2026-02-17 16:11       ` Junio C Hamano
2026-02-17 16:13         ` Patrick Steinhardt
2026-02-13 23:55   ` [PATCH v2 04/13] config: format int64s gently Derrick Stolee via GitGitGadget
2026-02-14  0:42     ` Junio C Hamano
2026-02-17  9:05     ` Patrick Steinhardt
2026-02-23  3:41       ` Derrick Stolee
2026-02-13 23:55   ` [PATCH v2 05/13] config: format bools gently Derrick Stolee via GitGitGadget
2026-02-13 23:55   ` [PATCH v2 06/13] config: format bools or ints gently Derrick Stolee via GitGitGadget
2026-02-17  9:05     ` Patrick Steinhardt
2026-02-23  3:25       ` Derrick Stolee
2026-02-13 23:55   ` [PATCH v2 07/13] config: format bools or strings in helper Derrick Stolee via GitGitGadget
2026-02-13 23:55   ` [PATCH v2 08/13] parse: add git_parse_maybe_pathname() Derrick Stolee via GitGitGadget
2026-02-13 23:55   ` [PATCH v2 09/13] config: format paths gently Derrick Stolee via GitGitGadget
2026-02-17  9:05     ` Patrick Steinhardt
2026-02-13 23:55   ` [PATCH v2 10/13] config: format expiry dates gently Derrick Stolee via GitGitGadget
2026-02-13 23:55   ` [PATCH v2 11/13] color: add color_parse_gently() Derrick Stolee via GitGitGadget
2026-02-17  9:05     ` Patrick Steinhardt
2026-02-17 16:20       ` Junio C Hamano
2026-02-23  2:12         ` Derrick Stolee
2026-02-23  5:03           ` Junio C Hamano
2026-02-13 23:55   ` [PATCH v2 12/13] config: format colors gently Derrick Stolee via GitGitGadget
2026-02-13 23:55   ` [PATCH v2 13/13] config: restructure format_config() Derrick Stolee via GitGitGadget
2026-02-17  9:05     ` Patrick Steinhardt
2026-02-23 12:26   ` [PATCH v3 00/13] Make 'git config list --type=' parse and filter types Derrick Stolee via GitGitGadget
2026-02-23 12:26     ` [PATCH v3 01/13] config: move show_all_config() Derrick Stolee via GitGitGadget
2026-02-23 12:26     ` [PATCH v3 02/13] config: add 'gently' parameter to format_config() Derrick Stolee via GitGitGadget
2026-02-23 12:26     ` Derrick Stolee via GitGitGadget [this message]
2026-02-23 12:26     ` [PATCH v3 04/13] config: format int64s gently Derrick Stolee via GitGitGadget
2026-02-23 12:26     ` [PATCH v3 05/13] config: format bools gently Derrick Stolee via GitGitGadget
2026-02-23 12:26     ` [PATCH v3 06/13] config: format bools or ints gently Derrick Stolee via GitGitGadget
2026-02-23 12:26     ` [PATCH v3 07/13] config: format bools or strings in helper Derrick Stolee via GitGitGadget
2026-02-23 12:26     ` [PATCH v3 08/13] config: format paths gently Derrick Stolee via GitGitGadget
2026-02-23 12:26     ` [PATCH v3 09/13] config: format expiry dates quietly Derrick Stolee via GitGitGadget
2026-02-23 12:26     ` [PATCH v3 10/13] color: add color_parse_quietly() Derrick Stolee via GitGitGadget
2026-02-23 12:26     ` [PATCH v3 11/13] config: format colors quietly Derrick Stolee via GitGitGadget
2026-02-23 12:26     ` [PATCH v3 12/13] config: restructure format_config() Derrick Stolee via GitGitGadget
2026-02-23 12:26     ` [PATCH v3 13/13] config: use an enum for type Derrick Stolee via GitGitGadget

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2b2a325b55a906cc8eba97f2020684f44c42bfc5.1771849615.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jn.avila@free.fr \
    --cc=kristofferhaugsbakk@fastmail.com \
    --cc=phillip.wood123@gmail.com \
    --cc=ps@pks.im \
    --cc=sandals@crustytoothpaste.net \
    --cc=stolee@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox