git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v5 2/2] builtin/config.c: prefer `--type=bool` over `--bool`, etc.

From
Taylor Blau <me@ttaylorr.com>
Date
Apr 6, 2018, 05:29 UTC
Message-ID
<20180406052907.GD60769@syl.local>
In-Reply-To
<cover.1522992443.git.me@ttaylorr.com>

`git config` has long allowed the ability for callers to provide a 'type specifier', which instructs `git config` to (1) ensure that incoming values are satisfiable under that type, and (2) that outgoing values are canonicalized under that type.

In another series, we propose to add extend this functionality with `--type=color` and `--default` to replace `--get-color`.

However, we traditionally use `--color` to mean "colorize this output", instead of "this value should be treated as a color".

Currently, `git config` does not support this kind of colorization, but we should be careful to avoid inhabiting this option too soon, so that `git config` can support `--type=color` (in the traditional sense) in the future, if that is desired.

In this patch, we prefer `--type=<int|bool|bool-or-int|...>` over `--int`, `--bool`, and etc. This allows the aforementioned upcoming patch to support querying a color value with a default via `--type=color --default=....`, without squandering `--color`.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
---
 Documentation/git-config.txt | 74 ++++++++++++++++++++----------------
 builtin/config.c             | 28 ++++++++++++++
 t/t1300-repo-config.sh       | 18 +++++++++
 3 files changed, 88 insertions(+), 32 deletions(-)
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index e09ed5d7d..31931ae00 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -9,13 +9,13 @@ git-config - Get and set repository or global options
 SYNOPSIS
 --------
 [verse]
-'git config' [<file-option>] [type] [--show-origin] [-z|--null] name [value [value_regex]]
-'git config' [<file-option>] [type] --add name value
-'git config' [<file-option>] [type] --replace-all name value [value_regex]
-'git config' [<file-option>] [type] [--show-origin] [-z|--null] --get name [value_regex]
-'git config' [<file-option>] [type] [--show-origin] [-z|--null] --get-all name [value_regex]
-'git config' [<file-option>] [type] [--show-origin] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]
-'git config' [<file-option>] [type] [-z|--null] --get-urlmatch name URL
+'git config' [<file-option>] [--type] [--show-origin] [-z|--null] name [value [value_regex]]
+'git config' [<file-option>] [--type] --add name value
+'git config' [<file-option>] [--type] --replace-all name value [value_regex]
+'git config' [<file-option>] [--type] [--show-origin] [-z|--null] --get name [value_regex]
+'git config' [<file-option>] [--type] [--show-origin] [-z|--null] --get-all name [value_regex]
+'git config' [<file-option>] [--type] [--show-origin] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]
+'git config' [<file-option>] [--type] [-z|--null] --get-urlmatch name URL
 'git config' [<file-option>] --unset name [value_regex]
 'git config' [<file-option>] --unset-all name [value_regex]
 'git config' [<file-option>] --rename-section old_name new_name
@@ -38,12 +38,13 @@ existing values that match the regexp are updated or unset.  If
 you want to handle the lines that do *not* match the regex, just
 prepend a single exclamation mark in front (see also <<EXAMPLES>>).
 
-The type specifier can be either `--int` or `--bool`, to make
-'git config' ensure that the variable(s) are of the given type and
-convert the value to the canonical form (simple decimal number for int,
-a "true" or "false" string for bool), or `--path`, which does some
-path expansion (see `--path` below).  If no type specifier is passed, no
-checks or transformations are performed on the value.
+The `--type` option requests 'git config' to ensure that the configured values
+assosciated with the given variable(s) are of the given type. When given
+`--type`, 'git config' will convert the value to that type's canonical form.
+ensure that the variable(s) are of the given type and convert the value to the
+canonical form. If no type specifier is passed, no checks or transformations are
+performed on the value. Callers may unset any pre-existing type specifiers with
+`--no-type`.
 
 When reading, the values are read from the system, global and
 repository local configuration files by default, and options
@@ -160,30 +161,39 @@ See also <<FILES>>.
 --list::
 	List all variables set in config file, along with their values.
 
---bool::
-	'git config' will ensure that the output is "true" or "false"
+--type <type>::
+  'git config' will ensure that any input or output is valid under the given
+  type constraint(s), and will canonicalize outgoing values in `<type>`'s
+  canonical form.
++
+Valid `<type>`'s include:
++
+- 'bool': canonicalize values as either "true" or "false".
+- 'int': canonicalize values as simple decimal numbers. An optional suffix of
+  'k', 'm', or 'g' will cause the value to be multiplied by 1024, 1048576, or
+  1073741824 prior to output.
+- 'bool-or-int': canonicalize according to either 'bool' or 'int', as described
+  above.
+- 'path': canonicalize by adding a leading `~` to the value of `$HOME` and
+  `~user` to the home directory for the specified user. This specifier has no
+  effect when setting the value (but you can use `git config section.variable
+  ~/` from the command line to let your shell do the expansion.)
+- 'expiry-date': canonicalize by converting from a fixed or relative date-string
+  to a timestamp. This specifier has no effect when setting the value.
++
 
+--bool::
 --int::
-	'git config' will ensure that the output is a simple
-	decimal number.  An optional value suffix of 'k', 'm', or 'g'
-	in the config file will cause the value to be multiplied
-	by 1024, 1048576, or 1073741824 prior to output.
-
 --bool-or-int::
-	'git config' will ensure that the output matches the format of
-	either --bool or --int, as described above.
-
 --path::
-	`git config` will expand a leading `~` to the value of
-	`$HOME`, and `~user` to the home directory for the
-	specified user.  This option has no effect when setting the
-	value (but you can use `git config section.variable ~/`
-	from the command line to let your shell do the expansion).
-
 --expiry-date::
-	`git config` will ensure that the output is converted from
-	a fixed or relative date-string to a timestamp. This option
-	has no effect when setting the value.
+  Historical options for selecting a type specifier. Prefer instead `--type`,
+  (see: above).
+
+--no-type::
+  Un-sets the previously set type specifier (if one was previously set). This
+  option requests that 'git config' not canonicalize the retrieved variable.
+  `--no-type` has no effect without `--type=<type>` or `--<type>`.
 
 -z::
 --null::
diff --git a/builtin/config.c b/builtin/config.c
index 92fb8d56b..6e1495eac 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -61,6 +61,33 @@ static int show_origin;
 #define TYPE_PATH		4
 #define TYPE_EXPIRY_DATE	5
 
+static int option_parse_type(const struct option *opt, const char *arg,
+			     int unset)
+{
+	int *type = opt->value;
+
+	if (unset) {
+		*type = 0;
+		return 0;
+	}
+
+	if (!strcmp(arg, "bool"))
+		*type = TYPE_BOOL;
+	else if (!strcmp(arg, "int"))
+		*type = TYPE_INT;
+	else if (!strcmp(arg, "bool-or-int"))
+		*type = TYPE_BOOL_OR_INT;
+	else if (!strcmp(arg, "path"))
+		*type = TYPE_PATH;
+	else if (!strcmp(arg, "expiry-date"))
+		*type = TYPE_EXPIRY_DATE;
+	else {
+		die(_("unrecognized --type argument, %s"), arg);
+		return 1;
+	}
+	return 0;
+}
+
 static struct option builtin_config_options[] = {
 	OPT_GROUP(N_("Config file location")),
 	OPT_BOOL(0, "global", &use_global_config, N_("use global config file")),
@@ -84,6 +111,7 @@ static struct option builtin_config_options[] = {
 	OPT_BIT(0, "get-color", &actions, N_("find the color configured: slot [default]"), ACTION_GET_COLOR),
 	OPT_BIT(0, "get-colorbool", &actions, N_("find the color setting: slot [stdout-is-tty]"), ACTION_GET_COLORBOOL),
 	OPT_GROUP(N_("Type")),
+	OPT_CALLBACK('t', "type", &type, N_("type"), N_("value is given this type"), option_parse_type),
 	OPT_SET_INT(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
 	OPT_SET_INT(0, "int", &type, N_("value is decimal number"), TYPE_INT),
 	OPT_SET_INT(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 24de37d54..f5ae80e9a 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -1613,6 +1613,7 @@ test_expect_success '--local requires a repo' '
 
 cat >.git/config <<-\EOF &&
 [core]
+foo = true
 number = 10
 EOF
 
@@ -1622,4 +1623,21 @@ test_expect_success 'later legacy specifiers are given precedence' '
 	test_cmp expect actual
 '
 
+test_expect_success '--type allows valid type specifiers' '
+	echo "true" >expect &&
+	git config --type=bool core.foo >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '--no-type unsets type specifiers' '
+	echo "10" >expect &&
+	git config --type=bool --no-type core.number >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '--type rejects unknown specifiers' '
+	test_must_fail git config --type=nonsense core.foo 2>error &&
+	test_i18ngrep "unrecognized --type argument" error
+'
+
 test_done
-- 
2.17.0
Previous: Taylor BlauNext: Eric Sunshine
Message 62 of 83 in “Teach `--default` to `git-config(1)`”
  1. 0/4 Teach `--default` to `git-config(1)`Taylor Blau, Mar 6, 2018
  2. 1/4 builtin/config: introduce `--default`Taylor Blau, Mar 6, 2018
  3. Jeff KingMar 6, 2018
  4. Eric SunshineMar 6, 2018
  5. Eric SunshineMar 6, 2018
  6. 3/4 config.c: introduce 'git_config_color' to parse ANSI colorsTaylor Blau, Mar 6, 2018
  7. Jeff KingMar 6, 2018
  8. 4/4 builtin/config: introduce `--color` type specifierTaylor Blau, Mar 6, 2018
  9. Jeff KingMar 6, 2018
  10. 2/4 Documentation: list all type specifiers in config proseTaylor Blau, Mar 6, 2018
  11. Jeff KingMar 6, 2018
  12. Junio C HamanoMar 6, 2018
  13. Taylor BlauMar 6, 2018
  14. 0/4 Teach `--default` to `git-config(1)`Taylor Blau, Mar 24, 2018
  15. 1/4 builtin/config: introduce `--default`Taylor Blau, Mar 24, 2018
  16. Jeff KingMar 26, 2018
  17. Taylor BlauMar 29, 2018
  18. 2/4 Documentation: list all type specifiers in config proseTaylor Blau, Mar 24, 2018
  19. Jeff KingMar 26, 2018
  20. Taylor BlauMar 29, 2018
  21. 3/4 config.c: introduce 'git_config_color' to parse ANSI colorsTaylor Blau, Mar 24, 2018
  22. 4/4 builtin/config: introduce `--color` type specifierTaylor Blau, Mar 24, 2018
  23. Jeff KingMar 26, 2018
  24. Taylor BlauMar 29, 2018
  25. Jeff KingMar 26, 2018
  26. 0/4 Teach `--default` to `git-config(1)`Taylor Blau, Mar 29, 2018
  27. 1/3 builtin/config: introduce `--default`Taylor Blau, Mar 29, 2018
  28. Junio C HamanoMar 30, 2018
  29. Taylor BlauApr 5, 2018
  30. Eric SunshineMar 30, 2018
  31. Taylor BlauApr 5, 2018
  32. 2/3 config.c: introduce 'git_config_color' to parse ANSI colorsTaylor Blau, Mar 29, 2018
  33. Eric SunshineMar 30, 2018
  34. Taylor BlauApr 5, 2018
  35. 3/3 builtin/config: introduce `color` type specifierTaylor Blau, Mar 29, 2018
  36. Junio C HamanoMar 30, 2018
  37. Taylor BlauApr 5, 2018
  38. Taylor BlauMar 29, 2018
  39. 0/3 Teach `--default` to `git-config(1)`Taylor Blau, Apr 5, 2018
  40. Jeff KingApr 5, 2018
  41. 0/2 builtin/config.c: prefer `--type=bool` over `--bool`, etc.Taylor Blau, Apr 6, 2018
  42. Taylor BlauApr 6, 2018
  43. 0/2 *** SUBJECT HERE ***Taylor Blau, Apr 6, 2018
  44. Jacob KellerApr 6, 2018
  45. 0/3 builtin/config: introduce `--default`Taylor Blau, Apr 6, 2018
  46. 0/3 Teach `--default` to `git-config(1)`Taylor Blau, Apr 10, 2018
  47. 1/3 builtin/config: introduce `--default`Taylor Blau, Apr 5, 2018
  48. Jeff KingApr 5, 2018
  49. Taylor BlauApr 6, 2018
  50. Junio C HamanoApr 8, 2018
  51. Taylor BlauApr 10, 2018
  52. Eric SunshineApr 5, 2018
  53. Taylor BlauApr 6, 2018
  54. 2/3 config.c: introduce 'git_config_color' to parse ANSI colorsTaylor Blau, Apr 5, 2018
  55. 3/3 builtin/config: introduce `color` type specifierTaylor Blau, Apr 5, 2018
  56. Jeff KingApr 5, 2018
  57. Eric SunshineApr 5, 2018
  58. Jeff KingApr 5, 2018
  59. Taylor BlauApr 6, 2018
  60. Taylor BlauApr 6, 2018
  61. 1/2 builtin/config.c: treat type specifiers singularlyTaylor Blau, Apr 6, 2018
  62. 2/2 builtin/config.c: prefer `--type=bool` over `--bool`, etc.Taylor Blau, Apr 6, 2018
  63. Eric SunshineApr 6, 2018
  64. Taylor BlauApr 6, 2018
  65. Jeff KingApr 6, 2018
  66. Taylor BlauApr 7, 2018
  67. 1/3 builtin/config: introduce `--default`Taylor Blau, Apr 6, 2018
  68. Eric SunshineApr 6, 2018
  69. Eric SunshineApr 6, 2018
  70. Taylor BlauApr 7, 2018
  71. Eric SunshineApr 7, 2018
  72. Taylor BlauApr 7, 2018
  73. Eric SunshineApr 7, 2018
  74. 2/3 config.c: introduce 'git_config_color' to parse ANSI colorsTaylor Blau, Apr 6, 2018
  75. 3/3 builtin/config: introduce `color` type specifierTaylor Blau, Apr 6, 2018
  76. Eric SunshineApr 6, 2018
  77. Taylor BlauApr 7, 2018
  78. 2/3 config.c: introduce 'git_config_color' to parse ANSI colorsTaylor Blau, Apr 10, 2018
  79. 3/3 builtin/config: introduce `color` type specifierTaylor Blau, Apr 10, 2018
  80. 3/3 builtin/config: introduce `color` type specifierTaylor Blau, Apr 10, 2018
  81. Junio C HamanoApr 10, 2018
  82. 1/3 builtin/config: introduce `--default`Taylor Blau, Apr 10, 2018
  83. Junio C HamanoApr 10, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.