{"thread":{"id":"64592","subject":"[PATCH] repo: add new flag --keys to git-repo-info","startedAt":"2025-12-07T19:05:53Z","lastAt":"2026-02-16T06:59:25Z","messageCount":40,"participants":["Lucas Seiki Oshiro","Junio C Hamano","Patrick Steinhardt","Jean-Noël AVILA"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"531801","messageId":"20251207190532.67107-1-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":null,"subject":"[PATCH] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2025-12-07T19:02:10Z","receivedAt":"2025-12-07T19:05:53Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"Currently, if the user wants to find what are the available keys,\nthey need to either check the documentation or to ask to all the\nkey-value pairs by using --all.\n\nAdd a new flag --keys for listing only the available keys without\nlisting the values.\n\nSigned-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n---\n\nHi!\n\nAfter the Junio's suggestion [1], this patch adds a new flag --keys to\ngit-repo-info. This new flag only prints the available keys, without\nprinting the corresponding values.\n\nThis patch is based on top of master bdc5341ff6 (The sixth batch,\n2025-12-05) with lo/repo-struct-z merged.\n\n[1] https://lore.kernel.org/git/xmqq8qg3do99.fsf@gitster.g/\n\n Documentation/git-repo.adoc |  4 ++++\n builtin/repo.c              | 17 +++++++++++++++++\n t/t1900-repo.sh             | 13 ++-----------\n 3 files changed, 23 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\nindex c4a78277df..f0f4d77db8 100644\n--- a/Documentation/git-repo.adoc\n+++ b/Documentation/git-repo.adoc\n@@ -9,6 +9,7 @@ SYNOPSIS\n --------\n [synopsis]\n git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\n+git repo info --keys\n git repo structure [--format=(table|keyvalue|nul) | -z]\n \n DESCRIPTION\n@@ -44,6 +45,9 @@ supported:\n +\n `-z` is an alias for `--format=nul`.\n \n+`info --keys`::\n+List all the available keys, one per line.\n+\n `structure [--format=(table|keyvalue|nul) | -z]`::\n \tRetrieve statistics about the current repository structure. The\n \tfollowing kinds of information are reported:\ndiff --git a/builtin/repo.c b/builtin/repo.c\nindex 0dd41b1778..45e9d59d55 100644\n--- a/builtin/repo.c\n+++ b/builtin/repo.c\n@@ -16,6 +16,7 @@\n \n static const char *const repo_usage[] = {\n \t\"git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\",\n+\t\"git repo info --keys\",\n \t\"git repo structure [--format=(table|keyvalue|nul) | -z]\",\n \tNULL\n };\n@@ -146,6 +147,16 @@ static int print_all_fields(struct repository *repo,\n \treturn 0;\n }\n \n+static int print_keys(void)\n+{\n+\tfor (size_t i = 0; i < ARRAY_SIZE(repo_info_fields); i++) {\n+\t\tconst struct field *field = &repo_info_fields[i];\n+\t\tputs(field->key);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int parse_format_cb(const struct option *opt,\n \t\t\t   const char *arg, int unset UNUSED)\n {\n@@ -170,6 +181,7 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n {\n \tenum output_format format = FORMAT_KEYVALUE;\n \tint all_keys = 0;\n+\tint show_keys = 0;\n \tstruct option options[] = {\n \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n \t\t\t       N_(\"output format\"),\n@@ -179,10 +191,15 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t\t\t       PARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\t       parse_format_cb),\n \t\tOPT_BOOL(0, \"all\", &all_keys, N_(\"print all keys/values\")),\n+\t\tOPT_BOOL(0, \"keys\", &show_keys, N_(\"show keys\")),\n \t\tOPT_END()\n \t};\n \n \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n+\n+\tif (show_keys)\n+\t\treturn print_keys();\n+\n \tif (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED)\n \t\tdie(_(\"unsupported output format\"));\n \ndiff --git a/t/t1900-repo.sh b/t/t1900-repo.sh\nindex 51d55f11a5..d6e84a78e5 100755\n--- a/t/t1900-repo.sh\n+++ b/t/t1900-repo.sh\n@@ -4,15 +4,6 @@ test_description='test git repo-info'\n \n . ./test-lib.sh\n \n-# git-repo-info keys. It must contain the same keys listed in the const\n-# repo_info_fields, in lexicographical order.\n-REPO_INFO_KEYS='\n-\tlayout.bare\n-\tlayout.shallow\n-\tobject.format\n-\treferences.format\n-'\n-\n # Test whether a key-value pair is correctly returned\n #\n # Usage: test_repo_info <label> <init command> <repo_name> <key> <expected value>\n@@ -119,8 +110,8 @@ test_expect_success 'git repo info uses the last requested format' '\n \ttest_cmp expected actual\n '\n \n-test_expect_success 'git repo info --all returns all key-value pairs' '\n-\tgit repo info $REPO_INFO_KEYS >expect &&\n+test_expect_success 'git repo info --all and git repo info $(git repo info --keys) output the same data' '\n+\tgit repo info $(git repo info --keys) >expect &&\n \tgit repo info --all >actual &&\n \ttest_cmp expect actual\n '\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"531804","messageId":"xmqqqzt6kkif.fsf@gitster.g","threadId":"64592","inReplyTo":"20251207190532.67107-1-lucasseikioshiro@gmail.com","subject":"Re: [PATCH] repo: add new flag --keys to git-repo-info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-12-07T22:14:00Z","receivedAt":"2025-12-07T22:14:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lucas Seiki Oshiro <lucasseikioshiro@gmail.com> writes:\n\n> Currently, if the user wants to find what are the available keys,\n> they need to either check the documentation or to ask to all the\n> key-value pairs by using --all.\n>\n> Add a new flag --keys for listing only the available keys without\n> listing the values.\n\nWe do not need to say \"Currently,\" but other than that the above is\nvery well written.  Easy to grok and to the point.\n\n>  [synopsis]\n>  git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\n> +git repo info --keys\n>  git repo structure [--format=(table|keyvalue|nul) | -z]\n\nSo \"git repo info --keys --all\" or \"git repo info --keys --format=...\"\nis not supported.  Does the implementation behave sensibly when given\nsuch nonsense commands?  Let's see.\n\n> @@ -170,6 +181,7 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n>  {\n>  \tenum output_format format = FORMAT_KEYVALUE;\n>  \tint all_keys = 0;\n> +\tint show_keys = 0;\n>  \tstruct option options[] = {\n>  \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n>  \t\t\t       N_(\"output format\"),\n> @@ -179,10 +191,15 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n>  \t\t\t       PARSE_OPT_NONEG | PARSE_OPT_NOARG,\n>  \t\t\t       parse_format_cb),\n>  \t\tOPT_BOOL(0, \"all\", &all_keys, N_(\"print all keys/values\")),\n> +\t\tOPT_BOOL(0, \"keys\", &show_keys, N_(\"show keys\")),\n>  \t\tOPT_END()\n>  \t};\n>  \n>  \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n> +\n> +\tif (show_keys)\n> +\t\treturn print_keys();\n> +\n>  \tif (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED)\n>  \t\tdie(_(\"unsupported output format\"));\n\nOK, so it is:\n\n    \"git repo info --all --keys\" and \"git repo info --keys layout.bare\"\n    both behave as if \"git repo --keys\" was given, ignoring\n    everything else.\n\nShouldn't \"--keys\" be explicitly marked incompatible with \"--all\"\nand remaining keys in argc/argv[]?\n\nWhile there is no strong reason why anybody must use NUL-terminated\noutput format, simply because repo_info_fields[] contains no tokens\nwith strange byte values, but just as principle, shouldn't\n\n    \"git repo info --keys -z\"\n\ndo what is naturally expected?\n\nPerhaps\n\n\tif (format != ...)\n\t\tdie(_(\"unsupported output format\"));\n\n\tif (show_keys && (all_keys || argc))\n\t\tdie(_(\"--keys cannot be used with a <key> or --all\"));\n\n\tif (show_keys)\n\t\treturn print_keys(output_format);\n\nwith a trivial update to print_keys() to support NUL-terminated\nrecords, instead of puts()?\n"},{"id":"531809","messageId":"aTZ6mmukjUld5V9M@pks.im","threadId":"64592","inReplyTo":"20251207190532.67107-1-lucasseikioshiro@gmail.com","subject":"Re: [PATCH] repo: add new flag --keys to git-repo-info","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-12-08T07:13:30Z","receivedAt":"2025-12-08T07:13:37Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Sun, Dec 07, 2025 at 04:02:10PM -0300, Lucas Seiki Oshiro wrote:\n> Currently, if the user wants to find what are the available keys,\n> they need to either check the documentation or to ask to all the\n\nThis sentence doesn't quite parse. I think you wanted to say \"ask for\nall\" instead of \"ask to all\" here.\n\nAll the other points were already covered by Junio, so I won't comment\non these parts.\n\nThanks!\n\nPatrick\n"},{"id":"531840","messageId":"5A4D4433-FD38-4BB0-81B6-3BAD33A30A74@gmail.com","threadId":"64592","inReplyTo":"xmqqqzt6kkif.fsf@gitster.g","subject":"Re: [PATCH] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2025-12-08T16:33:59Z","receivedAt":"2025-12-08T16:34:14Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"\n> We do not need to say \"Currently,\" but other than that the above is\n> very well written.  Easy to grok and to the point.\n\nThanks!\n\n> Shouldn't \"--keys\" be explicitly marked incompatible with \"--all\"\n> and remaining keys in argc/argv[]?\n\nYes, I'll work on that.\n\n> While there is no strong reason why anybody must use NUL-terminated\n> output format, simply because repo_info_fields[] contains no tokens\n> with strange byte values, but just as principle, shouldn't\n> \n>    \"git repo info --keys -z\"\n> \n> do what is naturally expected?\n\nHmmm... Perhaps it's too much for this simple flag. `-z` is tied to\n--format here, and if we want to support -z we'll also need to \nsupport --format.\n\nWhat about adding a \"default\" format for --format? This way, it\nwould translate to:\n\n- keyvalue, when using info without --keys\n- table, when using structure\n- using puts, when using info with --keys\n\nAnother solution, of course, would be aborting when --format, -z or\n--all are used with --keys.\n"},{"id":"531914","messageId":"20251209194616.61620-1-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20251207190532.67107-1-lucasseikioshiro@gmail.com","subject":"[PATCH v2 0/2] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2025-12-09T19:36:01Z","receivedAt":"2025-12-09T19:46:41Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"Hi!\n\nThis patch series adds a new flag --keys to git-repo-info. This new flag\nonly prints the available keys, without printing the corresponding\nvalues.\n\nThe main change in this version is the compatibility with the flags -z\nand --format, allowing the keys to be printed following the\nnull-terminated format.\n\nThis patch is based on top of master bdc5341ff6 (The sixth batch, \n2025-12-05) with lo/repo-struct-z merged.\n\nLucas Seiki Oshiro (2):\n  repo: add a default output format to enum output_format\n  repo: add new flag --keys to git-repo-info\n\n Documentation/git-repo.adoc | 11 ++++++++++\n builtin/repo.c              | 41 ++++++++++++++++++++++++++++++++++++-\n t/t1900-repo.sh             | 33 +++++++++++++++++++----------\n 3 files changed, 73 insertions(+), 12 deletions(-)\n\nRange-diff against v1:\n-:  ---------- > 1:  9eb2549806 repo: add a default output format to enum output_format\n1:  1b9b7dceb7 ! 2:  c5b7ba8824 repo: add new flag --keys to git-repo-info\n    @@ Metadata\n      ## Commit message ##\n         repo: add new flag --keys to git-repo-info\n     \n    -    Currently, if the user wants to find what are the available keys,\n    -    they need to either check the documentation or to ask to all the\n    -    key-value pairs by using --all.\n    +    If the user wants to find what are the available keys, they need to\n    +    either check the documentation or to ask for all the key-value pairs\n    +    by using --all.\n     \n         Add a new flag --keys for listing only the available keys without\n         listing the values.\n    @@ Documentation/git-repo.adoc: SYNOPSIS\n      --------\n      [synopsis]\n      git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\n    -+git repo info --keys\n    ++git repo info --keys [--format=(default|nul) | -z]\n      git repo structure [--format=(table|keyvalue|nul) | -z]\n      \n      DESCRIPTION\n    @@ Documentation/git-repo.adoc: supported:\n      +\n      `-z` is an alias for `--format=nul`.\n      \n    -+`info --keys`::\n    -+List all the available keys, one per line.\n    ++`info --keys [--format=(default|nul) | -z]`::\n    ++\tList all the available keys, one per line. The output format can be chosen\n    ++\tthrough the flag `--format`. The following formats are supported:\n    +++\n    ++`default`:::\n    ++\toutput the keys one per line.\n    ++\n    ++`nul`:::\n    ++\tsimilar to `default`, but using a NUL character after each value.\n     +\n      `structure [--format=(table|keyvalue|nul) | -z]`::\n      \tRetrieve statistics about the current repository structure. The\n    @@ builtin/repo.c\n      \n      static const char *const repo_usage[] = {\n      \t\"git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\",\n    -+\t\"git repo info --keys\",\n    ++\t\"git repo info --keys [--format=(default|nul) | -z]\",\n      \t\"git repo structure [--format=(table|keyvalue|nul) | -z]\",\n      \tNULL\n      };\n    @@ builtin/repo.c: static int print_all_fields(struct repository *repo,\n      \treturn 0;\n      }\n      \n    -+static int print_keys(void)\n    ++static int print_keys(enum output_format format)\n     +{\n    ++\tchar sep;\n    ++\n    ++\tswitch (format) {\n    ++\tcase FORMAT_DEFAULT:\n    ++\t\tsep = '\\n';\n    ++\t\tbreak;\n    ++\tcase FORMAT_NUL_TERMINATED:\n    ++\t\tsep = '\\0';\n    ++\t\tbreak;\n    ++\tdefault:\n    ++\t\tdie(_(\"--keys can only be used with --format=default or --format=nul\"));\n    ++\t}\n    ++\n     +\tfor (size_t i = 0; i < ARRAY_SIZE(repo_info_fields); i++) {\n     +\t\tconst struct field *field = &repo_info_fields[i];\n    -+\t\tputs(field->key);\n    ++\t\tprintf(\"%s%c\", field->key, sep);\n     +\t}\n     +\n     +\treturn 0;\n    @@ builtin/repo.c: static int print_all_fields(struct repository *repo,\n      {\n     @@ builtin/repo.c: static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n      {\n    - \tenum output_format format = FORMAT_KEYVALUE;\n    + \tenum output_format format = FORMAT_DEFAULT;\n      \tint all_keys = 0;\n     +\tint show_keys = 0;\n      \tstruct option options[] = {\n    @@ builtin/repo.c: static int cmd_repo_info(int argc, const char **argv, const char\n      \t};\n      \n      \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n    + \n    ++\tif (show_keys && (all_keys || argc))\n    ++\t\tdie(_(\"--keys cannot be used with a <key> or --all\"));\n     +\n     +\tif (show_keys)\n    -+\t\treturn print_keys();\n    ++\t\treturn print_keys(format);\n     +\n    - \tif (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED)\n    - \t\tdie(_(\"unsupported output format\"));\n    + \tif (format == FORMAT_DEFAULT)\n    + \t\tformat = FORMAT_KEYVALUE;\n      \n     \n      ## t/t1900-repo.sh ##\n    @@ t/t1900-repo.sh: test_expect_success 'git repo info uses the last requested form\n      \tgit repo info --all >actual &&\n      \ttest_cmp expect actual\n      '\n    +@@ t/t1900-repo.sh: test_expect_success 'git repo info --all <key> aborts' '\n    + \ttest_cmp expect actual\n    + '\n    + \n    ++test_expect_success 'git repo info --keys --format=nul uses nul-terminated output' '\n    ++\tgit repo info --keys --format=default >default &&\n    ++\tlf_to_nul <default > expect &&\n    ++\tgit repo info --keys --format=nul >actual &&\n    ++\ttest_cmp expect actual\n    ++'\n    ++\n    ++test_expect_success 'git repo info --keys aborts when using --format other than default or nul' '\n    ++\techo \"fatal: --keys can only be used with --format=default or --format=nul\" >expect &&\n    ++\ttest_must_fail git repo info --keys --format=keyvalue 2>actual &&\n    ++\ttest_cmp expect actual\n    ++'\n    ++\n    ++test_expect_success 'git repo info --keys aborts when requesting keys' '\n    ++\techo \"fatal: --keys cannot be used with a <key> or --all\" >expect &&\n    ++\ttest_must_fail git repo info --keys --all 2>actual_all &&\n    ++\ttest_must_fail git repo info --keys some.key 2>actual_key &&\n    ++\ttest_cmp expect actual_all &&\n    ++\ttest_cmp expect actual_key\n    ++'\n    + test_done\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"531915","messageId":"20251209194616.61620-2-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20251209194616.61620-1-lucasseikioshiro@gmail.com","subject":"[PATCH v2 1/2] repo: add a default output format to enum output_format","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2025-12-09T19:36:02Z","receivedAt":"2025-12-09T19:46:44Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"Add a `FORMAT_DEFAULT` value to `enum output_format`. Change the initial\nvalue of `format` to `FORMAT_DEFAULT` in cmd_repo_info, indicating that\nthe initial value hasn't been changed. Also map the string \"default\" to\nthis new value in `parse_format_cb`, allowing future patches to add\nsupport to --format=default.\n\nSigned-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n---\n builtin/repo.c | 9 ++++++++-\n 1 file changed, 8 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/repo.c b/builtin/repo.c\nindex 0dd41b1778..1cd12e7eea 100644\n--- a/builtin/repo.c\n+++ b/builtin/repo.c\n@@ -23,6 +23,7 @@ static const char *const repo_usage[] = {\n typedef int get_value_fn(struct repository *repo, struct strbuf *buf);\n \n enum output_format {\n+\tFORMAT_DEFAULT,\n \tFORMAT_TABLE,\n \tFORMAT_KEYVALUE,\n \tFORMAT_NUL_TERMINATED,\n@@ -159,6 +160,8 @@ static int parse_format_cb(const struct option *opt,\n \t\t*format = FORMAT_KEYVALUE;\n \telse if (!strcmp(arg, \"table\"))\n \t\t*format = FORMAT_TABLE;\n+\telse if (!strcmp(arg, \"default\"))\n+\t\t*format = FORMAT_DEFAULT;\n \telse\n \t\tdie(_(\"invalid format '%s'\"), arg);\n \n@@ -168,7 +171,7 @@ static int parse_format_cb(const struct option *opt,\n static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t\t\t struct repository *repo)\n {\n-\tenum output_format format = FORMAT_KEYVALUE;\n+\tenum output_format format = FORMAT_DEFAULT;\n \tint all_keys = 0;\n \tstruct option options[] = {\n \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n@@ -183,6 +186,10 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t};\n \n \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n+\n+\tif (format == FORMAT_DEFAULT)\n+\t\tformat = FORMAT_KEYVALUE;\n+\n \tif (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED)\n \t\tdie(_(\"unsupported output format\"));\n \n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"531916","messageId":"20251209194616.61620-3-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20251209194616.61620-1-lucasseikioshiro@gmail.com","subject":"[PATCH v2 2/2] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2025-12-09T19:36:03Z","receivedAt":"2025-12-09T19:46:46Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"If the user wants to find what are the available keys, they need to\neither check the documentation or to ask for all the key-value pairs\nby using --all.\n\nAdd a new flag --keys for listing only the available keys without\nlisting the values.\n\nSigned-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n---\n Documentation/git-repo.adoc | 11 +++++++++++\n builtin/repo.c              | 32 ++++++++++++++++++++++++++++++++\n t/t1900-repo.sh             | 33 ++++++++++++++++++++++-----------\n 3 files changed, 65 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\nindex c4a78277df..fd0683631c 100644\n--- a/Documentation/git-repo.adoc\n+++ b/Documentation/git-repo.adoc\n@@ -9,6 +9,7 @@ SYNOPSIS\n --------\n [synopsis]\n git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\n+git repo info --keys [--format=(default|nul) | -z]\n git repo structure [--format=(table|keyvalue|nul) | -z]\n \n DESCRIPTION\n@@ -44,6 +45,16 @@ supported:\n +\n `-z` is an alias for `--format=nul`.\n \n+`info --keys [--format=(default|nul) | -z]`::\n+\tList all the available keys, one per line. The output format can be chosen\n+\tthrough the flag `--format`. The following formats are supported:\n++\n+`default`:::\n+\toutput the keys one per line.\n+\n+`nul`:::\n+\tsimilar to `default`, but using a NUL character after each value.\n+\n `structure [--format=(table|keyvalue|nul) | -z]`::\n \tRetrieve statistics about the current repository structure. The\n \tfollowing kinds of information are reported:\ndiff --git a/builtin/repo.c b/builtin/repo.c\nindex 1cd12e7eea..48341f9245 100644\n--- a/builtin/repo.c\n+++ b/builtin/repo.c\n@@ -16,6 +16,7 @@\n \n static const char *const repo_usage[] = {\n \t\"git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\",\n+\t\"git repo info --keys [--format=(default|nul) | -z]\",\n \t\"git repo structure [--format=(table|keyvalue|nul) | -z]\",\n \tNULL\n };\n@@ -147,6 +148,29 @@ static int print_all_fields(struct repository *repo,\n \treturn 0;\n }\n \n+static int print_keys(enum output_format format)\n+{\n+\tchar sep;\n+\n+\tswitch (format) {\n+\tcase FORMAT_DEFAULT:\n+\t\tsep = '\\n';\n+\t\tbreak;\n+\tcase FORMAT_NUL_TERMINATED:\n+\t\tsep = '\\0';\n+\t\tbreak;\n+\tdefault:\n+\t\tdie(_(\"--keys can only be used with --format=default or --format=nul\"));\n+\t}\n+\n+\tfor (size_t i = 0; i < ARRAY_SIZE(repo_info_fields); i++) {\n+\t\tconst struct field *field = &repo_info_fields[i];\n+\t\tprintf(\"%s%c\", field->key, sep);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int parse_format_cb(const struct option *opt,\n \t\t\t   const char *arg, int unset UNUSED)\n {\n@@ -173,6 +197,7 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n {\n \tenum output_format format = FORMAT_DEFAULT;\n \tint all_keys = 0;\n+\tint show_keys = 0;\n \tstruct option options[] = {\n \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n \t\t\t       N_(\"output format\"),\n@@ -182,11 +207,18 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t\t\t       PARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\t       parse_format_cb),\n \t\tOPT_BOOL(0, \"all\", &all_keys, N_(\"print all keys/values\")),\n+\t\tOPT_BOOL(0, \"keys\", &show_keys, N_(\"show keys\")),\n \t\tOPT_END()\n \t};\n \n \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n \n+\tif (show_keys && (all_keys || argc))\n+\t\tdie(_(\"--keys cannot be used with a <key> or --all\"));\n+\n+\tif (show_keys)\n+\t\treturn print_keys(format);\n+\n \tif (format == FORMAT_DEFAULT)\n \t\tformat = FORMAT_KEYVALUE;\n \ndiff --git a/t/t1900-repo.sh b/t/t1900-repo.sh\nindex 51d55f11a5..e8802413a6 100755\n--- a/t/t1900-repo.sh\n+++ b/t/t1900-repo.sh\n@@ -4,15 +4,6 @@ test_description='test git repo-info'\n \n . ./test-lib.sh\n \n-# git-repo-info keys. It must contain the same keys listed in the const\n-# repo_info_fields, in lexicographical order.\n-REPO_INFO_KEYS='\n-\tlayout.bare\n-\tlayout.shallow\n-\tobject.format\n-\treferences.format\n-'\n-\n # Test whether a key-value pair is correctly returned\n #\n # Usage: test_repo_info <label> <init command> <repo_name> <key> <expected value>\n@@ -119,8 +110,8 @@ test_expect_success 'git repo info uses the last requested format' '\n \ttest_cmp expected actual\n '\n \n-test_expect_success 'git repo info --all returns all key-value pairs' '\n-\tgit repo info $REPO_INFO_KEYS >expect &&\n+test_expect_success 'git repo info --all and git repo info $(git repo info --keys) output the same data' '\n+\tgit repo info $(git repo info --keys) >expect &&\n \tgit repo info --all >actual &&\n \ttest_cmp expect actual\n '\n@@ -131,4 +122,24 @@ test_expect_success 'git repo info --all <key> aborts' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'git repo info --keys --format=nul uses nul-terminated output' '\n+\tgit repo info --keys --format=default >default &&\n+\tlf_to_nul <default > expect &&\n+\tgit repo info --keys --format=nul >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git repo info --keys aborts when using --format other than default or nul' '\n+\techo \"fatal: --keys can only be used with --format=default or --format=nul\" >expect &&\n+\ttest_must_fail git repo info --keys --format=keyvalue 2>actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git repo info --keys aborts when requesting keys' '\n+\techo \"fatal: --keys cannot be used with a <key> or --all\" >expect &&\n+\ttest_must_fail git repo info --keys --all 2>actual_all &&\n+\ttest_must_fail git repo info --keys some.key 2>actual_key &&\n+\ttest_cmp expect actual_all &&\n+\ttest_cmp expect actual_key\n+'\n test_done\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"533044","messageId":"568D8DB5-AED5-4A6E-88D8-890F9E11A00B@gmail.com","threadId":"64592","inReplyTo":"20251209194616.61620-1-lucasseikioshiro@gmail.com","subject":"Re: [PATCH v2 0/2] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-05T13:57:23Z","receivedAt":"2026-01-05T13:57:38Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"Hello, everyone, and happy new year!\n\nSorry to bother you with this, but do you have any comments about this\npatch?\n\nThanks!\n"},{"id":"533047","messageId":"aVvIOVVKZVjGCDrL@pks.im","threadId":"64592","inReplyTo":"20251209194616.61620-3-lucasseikioshiro@gmail.com","subject":"Re: [PATCH v2 2/2] repo: add new flag --keys to git-repo-info","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-01-05T14:18:33Z","receivedAt":"2026-01-05T14:18:40Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Dec 09, 2025 at 04:36:03PM -0300, Lucas Seiki Oshiro wrote:\n> diff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\n> index c4a78277df..fd0683631c 100644\n> --- a/Documentation/git-repo.adoc\n> +++ b/Documentation/git-repo.adoc\n> @@ -9,6 +9,7 @@ SYNOPSIS\n>  --------\n>  [synopsis]\n>  git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\n> +git repo info --keys [--format=(default|nul) | -z]\n>  git repo structure [--format=(table|keyvalue|nul) | -z]\n>  \n>  DESCRIPTION\n\nThe synopsis should have been updated in the preceding commit to mention\n\"default\" for `git repo info`.\n\n> @@ -131,4 +122,24 @@ test_expect_success 'git repo info --all <key> aborts' '\n>  \ttest_cmp expect actual\n>  '\n>  \n> +test_expect_success 'git repo info --keys --format=nul uses nul-terminated output' '\n> +\tgit repo info --keys --format=default >default &&\n> +\tlf_to_nul <default > expect &&\n\nStyle nit: there shouldn't be a space between \"> expect\".\n\nPatrick\n"},{"id":"533048","messageId":"aVvIQYdsrB8vAJ_R@pks.im","threadId":"64592","inReplyTo":"20251209194616.61620-2-lucasseikioshiro@gmail.com","subject":"Re: [PATCH v2 1/2] repo: add a default output format to enum output_format","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-01-05T14:18:41Z","receivedAt":"2026-01-05T14:18:47Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Dec 09, 2025 at 04:36:02PM -0300, Lucas Seiki Oshiro wrote:\n> Add a `FORMAT_DEFAULT` value to `enum output_format`. Change the initial\n> value of `format` to `FORMAT_DEFAULT` in cmd_repo_info, indicating that\n> the initial value hasn't been changed. Also map the string \"default\" to\n> this new value in `parse_format_cb`, allowing future patches to add\n> support to --format=default.\n\nThis is missing a test. It would for example be nice to verify that\n\"--format=nul --format=default\" does the expected thing.\n\nAlso, I didn't see `git repo structure` being updated. Should we do that\nso that both subcommands know to handle the \"default\" format?\n\nPatrick\n"},{"id":"533049","messageId":"aVvIX42uh2L4yIO7@pks.im","threadId":"64592","inReplyTo":"568D8DB5-AED5-4A6E-88D8-890F9E11A00B@gmail.com","subject":"Re: [PATCH v2 0/2] repo: add new flag --keys to git-repo-info","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-01-05T14:19:11Z","receivedAt":"2026-01-05T14:19:16Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Hi Lucas,\n\nOn Mon, Jan 05, 2026 at 10:57:23AM -0300, Lucas Seiki Oshiro wrote:\n> Hello, everyone, and happy new year!\n> \n> Sorry to bother you with this, but do you have any comments about this\n> patch?\n\nno need to be sorry, I lost track of this series and didn't have it on\nmy radar anymore. I've left some comments now, thanks!\n\nPatrick\n"},{"id":"533241","messageId":"6D2CDFA6-FB52-4BFD-B800-B01B5E484038@gmail.com","threadId":"64592","inReplyTo":"aVvIQYdsrB8vAJ_R@pks.im","subject":"Re: [PATCH v2 1/2] repo: add a default output format to enum output_format","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-07T21:28:59Z","receivedAt":"2026-01-07T21:29:12Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"\n> This is missing a test.\n\nIndeed, I'll add a test for `--format=default`.\n\n> It would for example be nice to verify that\n> \"--format=nul --format=default\" does the expected thing.\n\nWould it be necessary? We already have a test asserting that the\nlast \"--format\" wins:\n\ntest_expect_success 'git repo info uses the last requested format' '\n\techo \"layout.bare=false\" >expected &&\n\tgit repo info --format=nul -z --format=keyvalue layout.bare >actual &&\n\ttest_cmp expected actual\n'\n\n> Also, I didn't see `git repo structure` being updated. Should we do that\n> so that both subcommands know to handle the \"default\" format?\n\nSure! I'll do that!\n"},{"id":"533261","messageId":"aV9LBNtCaMMTlc8l@pks.im","threadId":"64592","inReplyTo":"6D2CDFA6-FB52-4BFD-B800-B01B5E484038@gmail.com","subject":"Re: [PATCH v2 1/2] repo: add a default output format to enum output_format","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-01-08T06:13:24Z","receivedAt":"2026-01-08T06:13:30Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Wed, Jan 07, 2026 at 06:28:59PM -0300, Lucas Seiki Oshiro wrote:\n> \n> > This is missing a test.\n> \n> Indeed, I'll add a test for `--format=default`.\n> \n> > It would for example be nice to verify that\n> > \"--format=nul --format=default\" does the expected thing.\n> \n> Would it be necessary? We already have a test asserting that the\n> last \"--format\" wins:\n> \n> test_expect_success 'git repo info uses the last requested format' '\n> \techo \"layout.bare=false\" >expected &&\n> \tgit repo info --format=nul -z --format=keyvalue layout.bare >actual &&\n> \ttest_cmp expected actual\n> '\n\nYup, but we don't have any test that verifies we do the right thing when\nthe user asks for the default format. So it's mostly an additional check\nthat the default format can be requested as expected, which would in the\nnormal case be a no-op as, well, it's the default. So if you specify a\ndifferent format before we verify that it can reset to the default.\n\nPatrick\n"},{"id":"533434","messageId":"20260109211554.90828-2-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20251207190532.67107-1-lucasseikioshiro@gmail.com","subject":"[PATCH v3 0/2] repo: add --format=default and --keys","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-09T20:31:51Z","receivedAt":"2026-01-09T21:26:02Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"Hi!\n\nThe main change in this version is that git-repo-structure now supports\n`--format=default`. This way, both git-repo-info and git-repo-structure\nnow can be used with `--format=default`, which resets the output format\nto the default one (`keyvalue` in repo-info, `table` in repo-structure).\n\nI'm also cc'ing Justin to see if he agrees with this change to\ngit-repo-structure.\n\nLucas Seiki Oshiro (2):\n  repo: add a default output format to enum output_format\n  repo: add new flag --keys to git-repo-info\n\n Documentation/git-repo.adoc | 30 ++++++++++++++++------\n builtin/repo.c              | 50 ++++++++++++++++++++++++++++++++++---\n t/t1900-repo.sh             | 46 ++++++++++++++++++++++++++--------\n t/t1901-repo-structure.sh   | 22 ++++++++++++++++\n 4 files changed, 126 insertions(+), 22 deletions(-)\n\nRange-diff against v2:\n1:  9eb2549806 ! 1:  97f8eee687 repo: add a default output format to enum output_format\n    @@ Metadata\n      ## Commit message ##\n         repo: add a default output format to enum output_format\n     \n    -    Add a `FORMAT_DEFAULT` value to `enum output_format`. Change the initial\n    -    value of `format` to `FORMAT_DEFAULT` in cmd_repo_info, indicating that\n    -    the initial value hasn't been changed. Also map the string \"default\" to\n    -    this new value in `parse_format_cb`, allowing future patches to add\n    -    support to --format=default.\n    +    Add \"default\" as an option for --format in both git-repo-info and\n    +    git-repo-structure. Using `--format=default` makes those commands use\n    +    their default output format.\n     \n         Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n     \n    + ## Documentation/git-repo.adoc ##\n    +@@ Documentation/git-repo.adoc: git-repo - Retrieve information about the repository\n    + SYNOPSIS\n    + --------\n    + [synopsis]\n    +-git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\n    +-git repo structure [--format=(table|keyvalue|nul) | -z]\n    ++git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\n    ++git repo structure [--format=(default|table|keyvalue|nul) | -z]\n    + \n    + DESCRIPTION\n    + -----------\n    +@@ Documentation/git-repo.adoc: THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.\n    + \n    + COMMANDS\n    + --------\n    +-`info [--format=(keyvalue|nul) | -z] [--all | <key>...]`::\n    ++`info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]`::\n    + \tRetrieve metadata-related information about the current repository. Only\n    + \tthe requested data will be returned based on their keys (see \"INFO KEYS\"\n    + \tsection below).\n    +@@ Documentation/git-repo.adoc: requested. The `--all` flag requests the values for all the available keys.\n    + The output format can be chosen through the flag `--format`. Two formats are\n    + supported:\n    + +\n    ++`default`:::\n    ++\tsynonym for `keyvalue`.\n    ++\n    + `keyvalue`:::\n    + \toutput key-value pairs one per line using the `=` character as\n    + \tthe delimiter between the key and the value. Values containing \"unusual\"\n    + \tcharacters are quoted as explained for the configuration variable\n    +-\t`core.quotePath` (see linkgit:git-config[1]). This is the default.\n    ++\t`core.quotePath` (see linkgit:git-config[1]).\n    + \n    + `nul`:::\n    + \tsimilar to `keyvalue`, but using a newline character as the delimiter\n    +@@ Documentation/git-repo.adoc: supported:\n    + +\n    + `-z` is an alias for `--format=nul`.\n    + \n    +-`structure [--format=(table|keyvalue|nul) | -z]`::\n    ++`structure [--format=(default|table|keyvalue|nul) | -z]`::\n    + \tRetrieve statistics about the current repository structure. The\n    + \tfollowing kinds of information are reported:\n    + +\n    +@@ Documentation/git-repo.adoc: supported:\n    + The output format can be chosen through the flag `--format`. Three formats are\n    + supported:\n    + +\n    ++`default`:::\n    ++\tsynonym for `table`.\n    ++\n    + `table`:::\n    + \tOutputs repository stats in a human-friendly table. This format may\n    +-\tchange and is not intended for machine parsing. This is the default\n    +-\tformat.\n    ++\tchange and is not intended for machine parsing.\n    + \n    + `keyvalue`:::\n    + \tEach line of output contains a key-value pair for a repository stat.\n    +\n      ## builtin/repo.c ##\n    -@@ builtin/repo.c: static const char *const repo_usage[] = {\n    +@@\n    + #include \"utf8.h\"\n    + \n    + static const char *const repo_usage[] = {\n    +-\t\"git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\",\n    +-\t\"git repo structure [--format=(table|keyvalue|nul) | -z]\",\n    ++\t\"git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\",\n    ++\t\"git repo structure [--format=(default|table|keyvalue|nul) | -z]\",\n    + \tNULL\n    + };\n    + \n      typedef int get_value_fn(struct repository *repo, struct strbuf *buf);\n      \n      enum output_format {\n    @@ builtin/repo.c: static int cmd_repo_info(int argc, const char **argv, const char\n      \tif (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED)\n      \t\tdie(_(\"unsupported output format\"));\n      \n    +@@ builtin/repo.c: static int cmd_repo_structure(int argc, const char **argv, const char *prefix,\n    + \tstruct stats_table table = {\n    + \t\t.rows = STRING_LIST_INIT_DUP,\n    + \t};\n    +-\tenum output_format format = FORMAT_TABLE;\n    ++\tenum output_format format = FORMAT_DEFAULT;\n    + \tstruct repo_structure stats = { 0 };\n    + \tstruct rev_info revs;\n    + \tint show_progress = -1;\n    +@@ builtin/repo.c: static int cmd_repo_structure(int argc, const char **argv, const char *prefix,\n    + \tif (argc)\n    + \t\tusage(_(\"too many arguments\"));\n    + \n    ++\tif (format == FORMAT_DEFAULT)\n    ++\t\tformat = FORMAT_TABLE;\n    ++\n    + \trepo_init_revisions(repo, &revs, prefix);\n    + \n    + \tif (show_progress < 0)\n    +\n    + ## t/t1900-repo.sh ##\n    +@@ t/t1900-repo.sh: test_expect_success 'git repo info --all <key> aborts' '\n    + \ttest_cmp expect actual\n    + '\n    + \n    ++test_expect_success '--format=default is a synonym for --format=keyvalue' '\n    ++\tgit repo info --all --format=keyvalue >expect &&\n    ++\tgit repo info --all --format=default >actual &&\n    ++\ttest_cmp expect actual\n    ++'\n    ++\n    ++test_expect_success '--format=default resets the format' '\n    ++\tgit repo info --all >expect &&\n    ++\tgit repo info --all --format=nul --format=default >actual &&\n    ++\ttest_cmp expect actual\n    ++'\n    ++\n    + test_done\n    +\n    + ## t/t1901-repo-structure.sh ##\n    +@@ t/t1901-repo-structure.sh: test_expect_success 'progress meter option' '\n    + \t)\n    + '\n    + \n    ++test_expect_success '--format=default is a synonym for --format=table' '\n    ++\ttest_when_finished \"rm -rf repo\" &&\n    ++\tgit init repo &&\n    ++\t(\n    ++\t\tcd repo &&\n    ++\t\tgit repo structure --format=table >expect &&\n    ++\t\tgit repo structure --format=default >actual &&\n    ++\t\ttest_cmp expect actual\n    ++\t)\n    ++'\n    ++\n    ++test_expect_success '--format=default resets the format' '\n    ++\ttest_when_finished \"rm -rf repo\" &&\n    ++\tgit init repo &&\n    ++\t(\n    ++\t\tcd repo &&\n    ++\t\tgit repo structure >expect &&\n    ++\t\tgit repo structure --format=nul --format=default >actual &&\n    ++\t\ttest_cmp expect actual\n    ++\t)\n    ++'\n    ++\n    + test_done\n2:  c5b7ba8824 ! 2:  0c7d3bca32 repo: add new flag --keys to git-repo-info\n    @@ Documentation/git-repo.adoc\n     @@ Documentation/git-repo.adoc: SYNOPSIS\n      --------\n      [synopsis]\n    - git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\n    + git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\n     +git repo info --keys [--format=(default|nul) | -z]\n    - git repo structure [--format=(table|keyvalue|nul) | -z]\n    + git repo structure [--format=(default|table|keyvalue|nul) | -z]\n      \n      DESCRIPTION\n     @@ Documentation/git-repo.adoc: supported:\n    @@ Documentation/git-repo.adoc: supported:\n     +`nul`:::\n     +\tsimilar to `default`, but using a NUL character after each value.\n     +\n    - `structure [--format=(table|keyvalue|nul) | -z]`::\n    + `structure [--format=(default|table|keyvalue|nul) | -z]`::\n      \tRetrieve statistics about the current repository structure. The\n      \tfollowing kinds of information are reported:\n     \n    @@ builtin/repo.c\n     @@\n      \n      static const char *const repo_usage[] = {\n    - \t\"git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\",\n    + \t\"git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\",\n     +\t\"git repo info --keys [--format=(default|nul) | -z]\",\n    - \t\"git repo structure [--format=(table|keyvalue|nul) | -z]\",\n    + \t\"git repo structure [--format=(default|table|keyvalue|nul) | -z]\",\n      \tNULL\n      };\n     @@ builtin/repo.c: static int print_all_fields(struct repository *repo,\n    @@ t/t1900-repo.sh: test_expect_success 'git repo info uses the last requested form\n      \tgit repo info --all >actual &&\n      \ttest_cmp expect actual\n      '\n    -@@ t/t1900-repo.sh: test_expect_success 'git repo info --all <key> aborts' '\n    +@@ t/t1900-repo.sh: test_expect_success '--format=default resets the format' '\n      \ttest_cmp expect actual\n      '\n      \n     +test_expect_success 'git repo info --keys --format=nul uses nul-terminated output' '\n     +\tgit repo info --keys --format=default >default &&\n    -+\tlf_to_nul <default > expect &&\n    ++\tlf_to_nul <default >expect &&\n     +\tgit repo info --keys --format=nul >actual &&\n     +\ttest_cmp expect actual\n     +'\n    @@ t/t1900-repo.sh: test_expect_success 'git repo info --all <key> aborts' '\n     +\ttest_cmp expect actual_all &&\n     +\ttest_cmp expect actual_key\n     +'\n    ++\n      test_done\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"533435","messageId":"20260109211554.90828-3-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20251207190532.67107-1-lucasseikioshiro@gmail.com","subject":"[PATCH v3 1/2] repo: add a default output format to enum output_format","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-09T20:31:52Z","receivedAt":"2026-01-09T21:26:04Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"Add \"default\" as an option for --format in both git-repo-info and\ngit-repo-structure. Using `--format=default` makes those commands use\ntheir default output format.\n\nSigned-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n---\n Documentation/git-repo.adoc | 19 ++++++++++++-------\n builtin/repo.c              | 18 ++++++++++++++----\n t/t1900-repo.sh             | 12 ++++++++++++\n t/t1901-repo-structure.sh   | 22 ++++++++++++++++++++++\n 4 files changed, 60 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\nindex 7d70270dfa..fa0e6600af 100644\n--- a/Documentation/git-repo.adoc\n+++ b/Documentation/git-repo.adoc\n@@ -8,8 +8,8 @@ git-repo - Retrieve information about the repository\n SYNOPSIS\n --------\n [synopsis]\n-git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\n-git repo structure [--format=(table|keyvalue|nul) | -z]\n+git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\n+git repo structure [--format=(default|table|keyvalue|nul) | -z]\n \n DESCRIPTION\n -----------\n@@ -19,7 +19,7 @@ THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.\n \n COMMANDS\n --------\n-`info [--format=(keyvalue|nul) | -z] [--all | <key>...]`::\n+`info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]`::\n \tRetrieve metadata-related information about the current repository. Only\n \tthe requested data will be returned based on their keys (see \"INFO KEYS\"\n \tsection below).\n@@ -30,11 +30,14 @@ requested. The `--all` flag requests the values for all the available keys.\n The output format can be chosen through the flag `--format`. Two formats are\n supported:\n +\n+`default`:::\n+\tsynonym for `keyvalue`.\n+\n `keyvalue`:::\n \toutput key-value pairs one per line using the `=` character as\n \tthe delimiter between the key and the value. Values containing \"unusual\"\n \tcharacters are quoted as explained for the configuration variable\n-\t`core.quotePath` (see linkgit:git-config[1]). This is the default.\n+\t`core.quotePath` (see linkgit:git-config[1]).\n \n `nul`:::\n \tsimilar to `keyvalue`, but using a newline character as the delimiter\n@@ -44,7 +47,7 @@ supported:\n +\n `-z` is an alias for `--format=nul`.\n \n-`structure [--format=(table|keyvalue|nul) | -z]`::\n+`structure [--format=(default|table|keyvalue|nul) | -z]`::\n \tRetrieve statistics about the current repository structure. The\n \tfollowing kinds of information are reported:\n +\n@@ -56,10 +59,12 @@ supported:\n The output format can be chosen through the flag `--format`. Three formats are\n supported:\n +\n+`default`:::\n+\tsynonym for `table`.\n+\n `table`:::\n \tOutputs repository stats in a human-friendly table. This format may\n-\tchange and is not intended for machine parsing. This is the default\n-\tformat.\n+\tchange and is not intended for machine parsing.\n \n `keyvalue`:::\n \tEach line of output contains a key-value pair for a repository stat.\ndiff --git a/builtin/repo.c b/builtin/repo.c\nindex 0ea045abc1..306d3fa2df 100644\n--- a/builtin/repo.c\n+++ b/builtin/repo.c\n@@ -17,14 +17,15 @@\n #include \"utf8.h\"\n \n static const char *const repo_usage[] = {\n-\t\"git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\",\n-\t\"git repo structure [--format=(table|keyvalue|nul) | -z]\",\n+\t\"git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\",\n+\t\"git repo structure [--format=(default|table|keyvalue|nul) | -z]\",\n \tNULL\n };\n \n typedef int get_value_fn(struct repository *repo, struct strbuf *buf);\n \n enum output_format {\n+\tFORMAT_DEFAULT,\n \tFORMAT_TABLE,\n \tFORMAT_KEYVALUE,\n \tFORMAT_NUL_TERMINATED,\n@@ -161,6 +162,8 @@ static int parse_format_cb(const struct option *opt,\n \t\t*format = FORMAT_KEYVALUE;\n \telse if (!strcmp(arg, \"table\"))\n \t\t*format = FORMAT_TABLE;\n+\telse if (!strcmp(arg, \"default\"))\n+\t\t*format = FORMAT_DEFAULT;\n \telse\n \t\tdie(_(\"invalid format '%s'\"), arg);\n \n@@ -170,7 +173,7 @@ static int parse_format_cb(const struct option *opt,\n static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t\t\t struct repository *repo)\n {\n-\tenum output_format format = FORMAT_KEYVALUE;\n+\tenum output_format format = FORMAT_DEFAULT;\n \tint all_keys = 0;\n \tstruct option options[] = {\n \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n@@ -185,6 +188,10 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t};\n \n \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n+\n+\tif (format == FORMAT_DEFAULT)\n+\t\tformat = FORMAT_KEYVALUE;\n+\n \tif (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED)\n \t\tdie(_(\"unsupported output format\"));\n \n@@ -638,7 +645,7 @@ static int cmd_repo_structure(int argc, const char **argv, const char *prefix,\n \tstruct stats_table table = {\n \t\t.rows = STRING_LIST_INIT_DUP,\n \t};\n-\tenum output_format format = FORMAT_TABLE;\n+\tenum output_format format = FORMAT_DEFAULT;\n \tstruct repo_structure stats = { 0 };\n \tstruct rev_info revs;\n \tint show_progress = -1;\n@@ -658,6 +665,9 @@ static int cmd_repo_structure(int argc, const char **argv, const char *prefix,\n \tif (argc)\n \t\tusage(_(\"too many arguments\"));\n \n+\tif (format == FORMAT_DEFAULT)\n+\t\tformat = FORMAT_TABLE;\n+\n \trepo_init_revisions(repo, &revs, prefix);\n \n \tif (show_progress < 0)\ndiff --git a/t/t1900-repo.sh b/t/t1900-repo.sh\nindex 51d55f11a5..e6670f0f58 100755\n--- a/t/t1900-repo.sh\n+++ b/t/t1900-repo.sh\n@@ -131,4 +131,16 @@ test_expect_success 'git repo info --all <key> aborts' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success '--format=default is a synonym for --format=keyvalue' '\n+\tgit repo info --all --format=keyvalue >expect &&\n+\tgit repo info --all --format=default >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '--format=default resets the format' '\n+\tgit repo info --all >expect &&\n+\tgit repo info --all --format=nul --format=default >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\ndiff --git a/t/t1901-repo-structure.sh b/t/t1901-repo-structure.sh\nindex 17ff164b05..9c5054c8db 100755\n--- a/t/t1901-repo-structure.sh\n+++ b/t/t1901-repo-structure.sh\n@@ -181,4 +181,26 @@ test_expect_success 'progress meter option' '\n \t)\n '\n \n+test_expect_success '--format=default is a synonym for --format=table' '\n+\ttest_when_finished \"rm -rf repo\" &&\n+\tgit init repo &&\n+\t(\n+\t\tcd repo &&\n+\t\tgit repo structure --format=table >expect &&\n+\t\tgit repo structure --format=default >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n+test_expect_success '--format=default resets the format' '\n+\ttest_when_finished \"rm -rf repo\" &&\n+\tgit init repo &&\n+\t(\n+\t\tcd repo &&\n+\t\tgit repo structure >expect &&\n+\t\tgit repo structure --format=nul --format=default >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n test_done\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"533436","messageId":"20260109211554.90828-4-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20251207190532.67107-1-lucasseikioshiro@gmail.com","subject":"[PATCH v3 2/2] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-09T20:31:53Z","receivedAt":"2026-01-09T21:26:07Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"If the user wants to find what are the available keys, they need to\neither check the documentation or to ask for all the key-value pairs\nby using --all.\n\nAdd a new flag --keys for listing only the available keys without\nlisting the values.\n\nSigned-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n---\n Documentation/git-repo.adoc | 11 +++++++++++\n builtin/repo.c              | 32 ++++++++++++++++++++++++++++++++\n t/t1900-repo.sh             | 34 +++++++++++++++++++++++-----------\n 3 files changed, 66 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\nindex fa0e6600af..4471816cc8 100644\n--- a/Documentation/git-repo.adoc\n+++ b/Documentation/git-repo.adoc\n@@ -9,6 +9,7 @@ SYNOPSIS\n --------\n [synopsis]\n git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\n+git repo info --keys [--format=(default|nul) | -z]\n git repo structure [--format=(default|table|keyvalue|nul) | -z]\n \n DESCRIPTION\n@@ -47,6 +48,16 @@ supported:\n +\n `-z` is an alias for `--format=nul`.\n \n+`info --keys [--format=(default|nul) | -z]`::\n+\tList all the available keys, one per line. The output format can be chosen\n+\tthrough the flag `--format`. The following formats are supported:\n++\n+`default`:::\n+\toutput the keys one per line.\n+\n+`nul`:::\n+\tsimilar to `default`, but using a NUL character after each value.\n+\n `structure [--format=(default|table|keyvalue|nul) | -z]`::\n \tRetrieve statistics about the current repository structure. The\n \tfollowing kinds of information are reported:\ndiff --git a/builtin/repo.c b/builtin/repo.c\nindex 306d3fa2df..bc10b2da0b 100644\n--- a/builtin/repo.c\n+++ b/builtin/repo.c\n@@ -18,6 +18,7 @@\n \n static const char *const repo_usage[] = {\n \t\"git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\",\n+\t\"git repo info --keys [--format=(default|nul) | -z]\",\n \t\"git repo structure [--format=(default|table|keyvalue|nul) | -z]\",\n \tNULL\n };\n@@ -149,6 +150,29 @@ static int print_all_fields(struct repository *repo,\n \treturn 0;\n }\n \n+static int print_keys(enum output_format format)\n+{\n+\tchar sep;\n+\n+\tswitch (format) {\n+\tcase FORMAT_DEFAULT:\n+\t\tsep = '\\n';\n+\t\tbreak;\n+\tcase FORMAT_NUL_TERMINATED:\n+\t\tsep = '\\0';\n+\t\tbreak;\n+\tdefault:\n+\t\tdie(_(\"--keys can only be used with --format=default or --format=nul\"));\n+\t}\n+\n+\tfor (size_t i = 0; i < ARRAY_SIZE(repo_info_fields); i++) {\n+\t\tconst struct field *field = &repo_info_fields[i];\n+\t\tprintf(\"%s%c\", field->key, sep);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int parse_format_cb(const struct option *opt,\n \t\t\t   const char *arg, int unset UNUSED)\n {\n@@ -175,6 +199,7 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n {\n \tenum output_format format = FORMAT_DEFAULT;\n \tint all_keys = 0;\n+\tint show_keys = 0;\n \tstruct option options[] = {\n \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n \t\t\t       N_(\"output format\"),\n@@ -184,11 +209,18 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t\t\t       PARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\t       parse_format_cb),\n \t\tOPT_BOOL(0, \"all\", &all_keys, N_(\"print all keys/values\")),\n+\t\tOPT_BOOL(0, \"keys\", &show_keys, N_(\"show keys\")),\n \t\tOPT_END()\n \t};\n \n \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n \n+\tif (show_keys && (all_keys || argc))\n+\t\tdie(_(\"--keys cannot be used with a <key> or --all\"));\n+\n+\tif (show_keys)\n+\t\treturn print_keys(format);\n+\n \tif (format == FORMAT_DEFAULT)\n \t\tformat = FORMAT_KEYVALUE;\n \ndiff --git a/t/t1900-repo.sh b/t/t1900-repo.sh\nindex e6670f0f58..14533b95a0 100755\n--- a/t/t1900-repo.sh\n+++ b/t/t1900-repo.sh\n@@ -4,15 +4,6 @@ test_description='test git repo-info'\n \n . ./test-lib.sh\n \n-# git-repo-info keys. It must contain the same keys listed in the const\n-# repo_info_fields, in lexicographical order.\n-REPO_INFO_KEYS='\n-\tlayout.bare\n-\tlayout.shallow\n-\tobject.format\n-\treferences.format\n-'\n-\n # Test whether a key-value pair is correctly returned\n #\n # Usage: test_repo_info <label> <init command> <repo_name> <key> <expected value>\n@@ -119,8 +110,8 @@ test_expect_success 'git repo info uses the last requested format' '\n \ttest_cmp expected actual\n '\n \n-test_expect_success 'git repo info --all returns all key-value pairs' '\n-\tgit repo info $REPO_INFO_KEYS >expect &&\n+test_expect_success 'git repo info --all and git repo info $(git repo info --keys) output the same data' '\n+\tgit repo info $(git repo info --keys) >expect &&\n \tgit repo info --all >actual &&\n \ttest_cmp expect actual\n '\n@@ -143,4 +134,25 @@ test_expect_success '--format=default resets the format' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'git repo info --keys --format=nul uses nul-terminated output' '\n+\tgit repo info --keys --format=default >default &&\n+\tlf_to_nul <default >expect &&\n+\tgit repo info --keys --format=nul >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git repo info --keys aborts when using --format other than default or nul' '\n+\techo \"fatal: --keys can only be used with --format=default or --format=nul\" >expect &&\n+\ttest_must_fail git repo info --keys --format=keyvalue 2>actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git repo info --keys aborts when requesting keys' '\n+\techo \"fatal: --keys cannot be used with a <key> or --all\" >expect &&\n+\ttest_must_fail git repo info --keys --all 2>actual_all &&\n+\ttest_must_fail git repo info --keys some.key 2>actual_key &&\n+\ttest_cmp expect actual_all &&\n+\ttest_cmp expect actual_key\n+'\n+\n test_done\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"533474","messageId":"xmqqo6n2rmij.fsf@gitster.g","threadId":"64592","inReplyTo":"20260109211554.90828-2-lucasseikioshiro@gmail.com","subject":"Re: [PATCH v3 0/2] repo: add --format=default and --keys","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-01-10T06:48:36Z","receivedAt":"2026-01-10T06:48:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lucas Seiki Oshiro <lucasseikioshiro@gmail.com> writes:\n\n> Hi!\n>\n> The main change in this version is that git-repo-structure now supports\n> `--format=default`. This way, both git-repo-info and git-repo-structure\n> now can be used with `--format=default`, which resets the output format\n> to the default one (`keyvalue` in repo-info, `table` in repo-structure).\n>\n> I'm also cc'ing Justin to see if he agrees with this change to\n> git-repo-structure.\n>\n> Lucas Seiki Oshiro (2):\n>   repo: add a default output format to enum output_format\n>   repo: add new flag --keys to git-repo-info\n\nHow does the bottommost commit relate to what has been queued on\nlo/repo-info-keys topic as ac3e74d2 (repo: add new flag --keys to\ngit-repo-info, 2025-12-09)?\n\n"},{"id":"533475","messageId":"xmqqjyxqrluv.fsf@gitster.g","threadId":"64592","inReplyTo":"xmqqo6n2rmij.fsf@gitster.g","subject":"Re: [PATCH v3 0/2] repo: add --format=default and --keys","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-01-10T07:02:48Z","receivedAt":"2026-01-10T07:02:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>> Lucas Seiki Oshiro (2):\n>>   repo: add a default output format to enum output_format\n>>   repo: add new flag --keys to git-repo-info\n>\n> How does the bottommost commit relate to what has been queued on\n> lo/repo-info-keys topic as ac3e74d2 (repo: add new flag --keys to\n> git-repo-info, 2025-12-09)?\n\nAh, nevermind.  These two are designed to replace the two patches on\nlo/repo-info-keys topic, so I'll discard the old ones and replace.\n"},{"id":"533479","messageId":"12814829.O9o76ZdvQC@piment-oiseau","threadId":"64592","inReplyTo":"20260109211554.90828-4-lucasseikioshiro@gmail.com","subject":"Re: [PATCH v3 2/2] repo: add new flag --keys to git-repo-info","fromName":"Jean-Noël AVILA","fromEmail":"avila.jn@gmail.com","sentAt":"2026-01-10T12:04:40Z","receivedAt":"2026-01-10T12:05:03Z","isPatch":true,"sender":{"key":"jn.avila@free.fr","avatar":"https://avatars.githubusercontent.com/u/156172?v=4"},"body":"On Friday, 9 January 2026 21:31:53 CET Lucas Seiki Oshiro wrote:\n> If the user wants to find what are the available keys, they need to\n> either check the documentation or to ask for all the key-value pairs\n> by using --all.\n> \n> Add a new flag --keys for listing only the available keys without\n> listing the values.\n> \n> Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n> ---\n>  Documentation/git-repo.adoc | 11 +++++++++++\n>  builtin/repo.c              | 32 ++++++++++++++++++++++++++++++++\n>  t/t1900-repo.sh             | 34 +++++++++++++++++++++++-----------\n>  3 files changed, 66 insertions(+), 11 deletions(-)\n> \n> diff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\n> index fa0e6600af..4471816cc8 100644\n> --- a/Documentation/git-repo.adoc\n> +++ b/Documentation/git-repo.adoc\n> @@ -9,6 +9,7 @@ SYNOPSIS\n>  --------\n>  [synopsis]\n>  git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\n> +git repo info --keys [--format=(default|nul) | -z]\n>  git repo structure [--format=(default|table|keyvalue|nul) | -z]\n> \n>  DESCRIPTION\n> @@ -47,6 +48,16 @@ supported:\n>  +\n>  `-z` is an alias for `--format=nul`.\n> \n> +`info --keys [--format=(default|nul) | -z]`::\n> +\tList all the available keys, one per line. The output format can be \nchosen\n> +\tthrough the flag `--format`. The following formats are supported:\n> ++\n> +`default`:::\n> +\toutput the keys one per line.\n> +\n> +`nul`:::\n> +\tsimilar to `default`, but using a NUL character after each value.\n\nWe use the placeholder format for character names: _NUL_\n\n\n\n\n"},{"id":"533507","messageId":"C2D91A8E-F034-4604-8B02-155BAADD14A2@gmail.com","threadId":"64592","inReplyTo":"12814829.O9o76ZdvQC@piment-oiseau","subject":"Re: [PATCH v3 2/2] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-10T22:00:35Z","receivedAt":"2026-01-10T22:18:28Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"\n> We use the placeholder format for character names: _NUL_\n\nThanks. I'll change it in v4 and I'll change other occurrences in this\ndocument in future patches.\n\n\n"},{"id":"533567","messageId":"aWSzjnqtvpwYnJlX@pks.im","threadId":"64592","inReplyTo":"20260109211554.90828-4-lucasseikioshiro@gmail.com","subject":"Re: [PATCH v3 2/2] repo: add new flag --keys to git-repo-info","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-01-12T08:40:46Z","receivedAt":"2026-01-12T08:40:52Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Fri, Jan 09, 2026 at 05:31:53PM -0300, Lucas Seiki Oshiro wrote:\n> diff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\n> index fa0e6600af..4471816cc8 100644\n> --- a/Documentation/git-repo.adoc\n> +++ b/Documentation/git-repo.adoc\n> @@ -47,6 +48,16 @@ supported:\n>  +\n>  `-z` is an alias for `--format=nul`.\n>  \n> +`info --keys [--format=(default|nul) | -z]`::\n> +\tList all the available keys, one per line. The output format can be chosen\n> +\tthrough the flag `--format`. The following formats are supported:\n> ++\n> +`default`:::\n> +\toutput the keys one per line.\n> +\n> +`nul`:::\n> +\tsimilar to `default`, but using a NUL character after each value.\n> +\n>  `structure [--format=(default|table|keyvalue|nul) | -z]`::\n>  \tRetrieve statistics about the current repository structure. The\n>  \tfollowing kinds of information are reported:\n\nI think it's slightly unfortunate that the default format cannot be\nexplicitly chosen. \"keyvalue\" of course doesn't make sense, but maybe we\nshould have a format \"newline\" that can be specified?\n\nOther than that the patches look good to me, thanks!\n\nPatrick\n"},{"id":"534194","messageId":"20260119210932.68893-1-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20251207190532.67107-1-lucasseikioshiro@gmail.com","subject":"[PATCH v4 0/2] repo: add --format=default and --keys","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-19T20:20:18Z","receivedAt":"2026-01-19T21:09:45Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"Hello, again!\n\nThis v4 addresses these two issues:\n\n1. NUL was replaced by _NUL_ in the documentation\n2. Now, the default output format of `git repo info --keys` is \"lines\"\n   and \"default\" is a synonym for it. I prefer to called it \"lines\"\n   instead of \"newline\" (as suggested by Patrick) because I thought that\n   it would be clear to the user\n\nLucas Seiki Oshiro (2):\n  repo: add a default output format to enum output_format\n  repo: add new flag --keys to git-repo-info\n\n Documentation/git-repo.adoc | 33 +++++++++++++++++-----\n builtin/repo.c              | 56 ++++++++++++++++++++++++++++++++++---\n t/t1900-repo.sh             | 54 +++++++++++++++++++++++++++--------\n t/t1901-repo-structure.sh   | 22 +++++++++++++++\n 4 files changed, 143 insertions(+), 22 deletions(-)\n\nRange-diff against v3:\n1:  97f8eee687 = 1:  7dabd62250 repo: add a default output format to enum output_format\n2:  0c7d3bca32 ! 2:  fba621fc4f repo: add new flag --keys to git-repo-info\n    @@ Documentation/git-repo.adoc: SYNOPSIS\n      --------\n      [synopsis]\n      git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\n    -+git repo info --keys [--format=(default|nul) | -z]\n    ++git repo info --keys [--format=(default|lines|nul) | -z]\n      git repo structure [--format=(default|table|keyvalue|nul) | -z]\n      \n      DESCRIPTION\n    @@ Documentation/git-repo.adoc: supported:\n      +\n      `-z` is an alias for `--format=nul`.\n      \n    -+`info --keys [--format=(default|nul) | -z]`::\n    ++`info --keys [--format=(default|lines|nul) | -z]`::\n     +\tList all the available keys, one per line. The output format can be chosen\n     +\tthrough the flag `--format`. The following formats are supported:\n     ++\n     +`default`:::\n    ++\tsynonym for `lines`.\n    ++\n    ++`lines`:::\n     +\toutput the keys one per line.\n     +\n     +`nul`:::\n    -+\tsimilar to `default`, but using a NUL character after each value.\n    ++\tsimilar to `default`, but using a _NUL_ character after each value.\n     +\n      `structure [--format=(default|table|keyvalue|nul) | -z]`::\n      \tRetrieve statistics about the current repository structure. The\n    @@ builtin/repo.c\n      \n      static const char *const repo_usage[] = {\n      \t\"git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\",\n    -+\t\"git repo info --keys [--format=(default|nul) | -z]\",\n    ++\t\"git repo info --keys [--format=(default|lines|nul) | -z]\",\n      \t\"git repo structure [--format=(default|table|keyvalue|nul) | -z]\",\n      \tNULL\n      };\n    +@@ builtin/repo.c: enum output_format {\n    + \tFORMAT_TABLE,\n    + \tFORMAT_KEYVALUE,\n    + \tFORMAT_NUL_TERMINATED,\n    ++\tFORMAT_LINES\n    + };\n    + \n    + struct field {\n     @@ builtin/repo.c: static int print_all_fields(struct repository *repo,\n      \treturn 0;\n      }\n    @@ builtin/repo.c: static int print_all_fields(struct repository *repo,\n     +{\n     +\tchar sep;\n     +\n    ++\tif (format == FORMAT_DEFAULT)\n    ++\t\tformat = FORMAT_LINES;\n    ++\n     +\tswitch (format) {\n    -+\tcase FORMAT_DEFAULT:\n    ++\tcase FORMAT_LINES:\n     +\t\tsep = '\\n';\n     +\t\tbreak;\n     +\tcase FORMAT_NUL_TERMINATED:\n    @@ builtin/repo.c: static int print_all_fields(struct repository *repo,\n      static int parse_format_cb(const struct option *opt,\n      \t\t\t   const char *arg, int unset UNUSED)\n      {\n    +@@ builtin/repo.c: static int parse_format_cb(const struct option *opt,\n    + \t\t*format = FORMAT_KEYVALUE;\n    + \telse if (!strcmp(arg, \"table\"))\n    + \t\t*format = FORMAT_TABLE;\n    ++\telse if (!strcmp(arg, \"lines\"))\n    ++\t\t*format = FORMAT_LINES;\n    + \telse if (!strcmp(arg, \"default\"))\n    + \t\t*format = FORMAT_DEFAULT;\n    + \telse\n     @@ builtin/repo.c: static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n      {\n      \tenum output_format format = FORMAT_DEFAULT;\n    @@ t/t1900-repo.sh: test_expect_success '--format=default resets the format' '\n     +\ttest_cmp expect actual_all &&\n     +\ttest_cmp expect actual_key\n     +'\n    ++\n    ++test_expect_success 'git repo info --keys uses lines as its default output format' '\n    ++\tgit repo info --keys --format=lines >expect &&\n    ++\tgit repo info --keys --format=default >actual_explicit &&\n    ++\tgit repo info --keys >actual_implicit &&\n    ++\ttest_cmp expect actual_explicit &&\n    ++\ttest_cmp expect actual_implicit\n    ++'\n     +\n      test_done\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"534195","messageId":"20260119210932.68893-2-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20260119210932.68893-1-lucasseikioshiro@gmail.com","subject":"[PATCH v4 1/2] repo: add a default output format to enum output_format","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-19T20:20:19Z","receivedAt":"2026-01-19T21:09:48Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"Add \"default\" as an option for --format in both git-repo-info and\ngit-repo-structure. Using `--format=default` makes those commands use\ntheir default output format.\n\nSigned-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n---\n Documentation/git-repo.adoc | 19 ++++++++++++-------\n builtin/repo.c              | 18 ++++++++++++++----\n t/t1900-repo.sh             | 12 ++++++++++++\n t/t1901-repo-structure.sh   | 22 ++++++++++++++++++++++\n 4 files changed, 60 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\nindex 7d70270dfa..fa0e6600af 100644\n--- a/Documentation/git-repo.adoc\n+++ b/Documentation/git-repo.adoc\n@@ -8,8 +8,8 @@ git-repo - Retrieve information about the repository\n SYNOPSIS\n --------\n [synopsis]\n-git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\n-git repo structure [--format=(table|keyvalue|nul) | -z]\n+git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\n+git repo structure [--format=(default|table|keyvalue|nul) | -z]\n \n DESCRIPTION\n -----------\n@@ -19,7 +19,7 @@ THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.\n \n COMMANDS\n --------\n-`info [--format=(keyvalue|nul) | -z] [--all | <key>...]`::\n+`info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]`::\n \tRetrieve metadata-related information about the current repository. Only\n \tthe requested data will be returned based on their keys (see \"INFO KEYS\"\n \tsection below).\n@@ -30,11 +30,14 @@ requested. The `--all` flag requests the values for all the available keys.\n The output format can be chosen through the flag `--format`. Two formats are\n supported:\n +\n+`default`:::\n+\tsynonym for `keyvalue`.\n+\n `keyvalue`:::\n \toutput key-value pairs one per line using the `=` character as\n \tthe delimiter between the key and the value. Values containing \"unusual\"\n \tcharacters are quoted as explained for the configuration variable\n-\t`core.quotePath` (see linkgit:git-config[1]). This is the default.\n+\t`core.quotePath` (see linkgit:git-config[1]).\n \n `nul`:::\n \tsimilar to `keyvalue`, but using a newline character as the delimiter\n@@ -44,7 +47,7 @@ supported:\n +\n `-z` is an alias for `--format=nul`.\n \n-`structure [--format=(table|keyvalue|nul) | -z]`::\n+`structure [--format=(default|table|keyvalue|nul) | -z]`::\n \tRetrieve statistics about the current repository structure. The\n \tfollowing kinds of information are reported:\n +\n@@ -56,10 +59,12 @@ supported:\n The output format can be chosen through the flag `--format`. Three formats are\n supported:\n +\n+`default`:::\n+\tsynonym for `table`.\n+\n `table`:::\n \tOutputs repository stats in a human-friendly table. This format may\n-\tchange and is not intended for machine parsing. This is the default\n-\tformat.\n+\tchange and is not intended for machine parsing.\n \n `keyvalue`:::\n \tEach line of output contains a key-value pair for a repository stat.\ndiff --git a/builtin/repo.c b/builtin/repo.c\nindex 0ea045abc1..306d3fa2df 100644\n--- a/builtin/repo.c\n+++ b/builtin/repo.c\n@@ -17,14 +17,15 @@\n #include \"utf8.h\"\n \n static const char *const repo_usage[] = {\n-\t\"git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\",\n-\t\"git repo structure [--format=(table|keyvalue|nul) | -z]\",\n+\t\"git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\",\n+\t\"git repo structure [--format=(default|table|keyvalue|nul) | -z]\",\n \tNULL\n };\n \n typedef int get_value_fn(struct repository *repo, struct strbuf *buf);\n \n enum output_format {\n+\tFORMAT_DEFAULT,\n \tFORMAT_TABLE,\n \tFORMAT_KEYVALUE,\n \tFORMAT_NUL_TERMINATED,\n@@ -161,6 +162,8 @@ static int parse_format_cb(const struct option *opt,\n \t\t*format = FORMAT_KEYVALUE;\n \telse if (!strcmp(arg, \"table\"))\n \t\t*format = FORMAT_TABLE;\n+\telse if (!strcmp(arg, \"default\"))\n+\t\t*format = FORMAT_DEFAULT;\n \telse\n \t\tdie(_(\"invalid format '%s'\"), arg);\n \n@@ -170,7 +173,7 @@ static int parse_format_cb(const struct option *opt,\n static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t\t\t struct repository *repo)\n {\n-\tenum output_format format = FORMAT_KEYVALUE;\n+\tenum output_format format = FORMAT_DEFAULT;\n \tint all_keys = 0;\n \tstruct option options[] = {\n \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n@@ -185,6 +188,10 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t};\n \n \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n+\n+\tif (format == FORMAT_DEFAULT)\n+\t\tformat = FORMAT_KEYVALUE;\n+\n \tif (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED)\n \t\tdie(_(\"unsupported output format\"));\n \n@@ -638,7 +645,7 @@ static int cmd_repo_structure(int argc, const char **argv, const char *prefix,\n \tstruct stats_table table = {\n \t\t.rows = STRING_LIST_INIT_DUP,\n \t};\n-\tenum output_format format = FORMAT_TABLE;\n+\tenum output_format format = FORMAT_DEFAULT;\n \tstruct repo_structure stats = { 0 };\n \tstruct rev_info revs;\n \tint show_progress = -1;\n@@ -658,6 +665,9 @@ static int cmd_repo_structure(int argc, const char **argv, const char *prefix,\n \tif (argc)\n \t\tusage(_(\"too many arguments\"));\n \n+\tif (format == FORMAT_DEFAULT)\n+\t\tformat = FORMAT_TABLE;\n+\n \trepo_init_revisions(repo, &revs, prefix);\n \n \tif (show_progress < 0)\ndiff --git a/t/t1900-repo.sh b/t/t1900-repo.sh\nindex 51d55f11a5..e6670f0f58 100755\n--- a/t/t1900-repo.sh\n+++ b/t/t1900-repo.sh\n@@ -131,4 +131,16 @@ test_expect_success 'git repo info --all <key> aborts' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success '--format=default is a synonym for --format=keyvalue' '\n+\tgit repo info --all --format=keyvalue >expect &&\n+\tgit repo info --all --format=default >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success '--format=default resets the format' '\n+\tgit repo info --all >expect &&\n+\tgit repo info --all --format=nul --format=default >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\ndiff --git a/t/t1901-repo-structure.sh b/t/t1901-repo-structure.sh\nindex 17ff164b05..9c5054c8db 100755\n--- a/t/t1901-repo-structure.sh\n+++ b/t/t1901-repo-structure.sh\n@@ -181,4 +181,26 @@ test_expect_success 'progress meter option' '\n \t)\n '\n \n+test_expect_success '--format=default is a synonym for --format=table' '\n+\ttest_when_finished \"rm -rf repo\" &&\n+\tgit init repo &&\n+\t(\n+\t\tcd repo &&\n+\t\tgit repo structure --format=table >expect &&\n+\t\tgit repo structure --format=default >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n+test_expect_success '--format=default resets the format' '\n+\ttest_when_finished \"rm -rf repo\" &&\n+\tgit init repo &&\n+\t(\n+\t\tcd repo &&\n+\t\tgit repo structure >expect &&\n+\t\tgit repo structure --format=nul --format=default >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n test_done\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"534196","messageId":"20260119210932.68893-3-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20260119210932.68893-1-lucasseikioshiro@gmail.com","subject":"[PATCH v4 2/2] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-19T20:20:20Z","receivedAt":"2026-01-19T21:09:51Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"If the user wants to find what are the available keys, they need to\neither check the documentation or to ask for all the key-value pairs\nby using --all.\n\nAdd a new flag --keys for listing only the available keys without\nlisting the values.\n\nSigned-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n---\n Documentation/git-repo.adoc | 14 +++++++++++++\n builtin/repo.c              | 38 +++++++++++++++++++++++++++++++++\n t/t1900-repo.sh             | 42 +++++++++++++++++++++++++++----------\n 3 files changed, 83 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\nindex fa0e6600af..2472345a7c 100644\n--- a/Documentation/git-repo.adoc\n+++ b/Documentation/git-repo.adoc\n@@ -9,6 +9,7 @@ SYNOPSIS\n --------\n [synopsis]\n git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\n+git repo info --keys [--format=(default|lines|nul) | -z]\n git repo structure [--format=(default|table|keyvalue|nul) | -z]\n \n DESCRIPTION\n@@ -47,6 +48,19 @@ supported:\n +\n `-z` is an alias for `--format=nul`.\n \n+`info --keys [--format=(default|lines|nul) | -z]`::\n+\tList all the available keys, one per line. The output format can be chosen\n+\tthrough the flag `--format`. The following formats are supported:\n++\n+`default`:::\n+\tsynonym for `lines`.\n+\n+`lines`:::\n+\toutput the keys one per line.\n+\n+`nul`:::\n+\tsimilar to `default`, but using a _NUL_ character after each value.\n+\n `structure [--format=(default|table|keyvalue|nul) | -z]`::\n \tRetrieve statistics about the current repository structure. The\n \tfollowing kinds of information are reported:\ndiff --git a/builtin/repo.c b/builtin/repo.c\nindex 306d3fa2df..2f698c5253 100644\n--- a/builtin/repo.c\n+++ b/builtin/repo.c\n@@ -18,6 +18,7 @@\n \n static const char *const repo_usage[] = {\n \t\"git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\",\n+\t\"git repo info --keys [--format=(default|lines|nul) | -z]\",\n \t\"git repo structure [--format=(default|table|keyvalue|nul) | -z]\",\n \tNULL\n };\n@@ -29,6 +30,7 @@ enum output_format {\n \tFORMAT_TABLE,\n \tFORMAT_KEYVALUE,\n \tFORMAT_NUL_TERMINATED,\n+\tFORMAT_LINES\n };\n \n struct field {\n@@ -149,6 +151,32 @@ static int print_all_fields(struct repository *repo,\n \treturn 0;\n }\n \n+static int print_keys(enum output_format format)\n+{\n+\tchar sep;\n+\n+\tif (format == FORMAT_DEFAULT)\n+\t\tformat = FORMAT_LINES;\n+\n+\tswitch (format) {\n+\tcase FORMAT_LINES:\n+\t\tsep = '\\n';\n+\t\tbreak;\n+\tcase FORMAT_NUL_TERMINATED:\n+\t\tsep = '\\0';\n+\t\tbreak;\n+\tdefault:\n+\t\tdie(_(\"--keys can only be used with --format=default or --format=nul\"));\n+\t}\n+\n+\tfor (size_t i = 0; i < ARRAY_SIZE(repo_info_fields); i++) {\n+\t\tconst struct field *field = &repo_info_fields[i];\n+\t\tprintf(\"%s%c\", field->key, sep);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int parse_format_cb(const struct option *opt,\n \t\t\t   const char *arg, int unset UNUSED)\n {\n@@ -162,6 +190,8 @@ static int parse_format_cb(const struct option *opt,\n \t\t*format = FORMAT_KEYVALUE;\n \telse if (!strcmp(arg, \"table\"))\n \t\t*format = FORMAT_TABLE;\n+\telse if (!strcmp(arg, \"lines\"))\n+\t\t*format = FORMAT_LINES;\n \telse if (!strcmp(arg, \"default\"))\n \t\t*format = FORMAT_DEFAULT;\n \telse\n@@ -175,6 +205,7 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n {\n \tenum output_format format = FORMAT_DEFAULT;\n \tint all_keys = 0;\n+\tint show_keys = 0;\n \tstruct option options[] = {\n \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n \t\t\t       N_(\"output format\"),\n@@ -184,11 +215,18 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t\t\t       PARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\t       parse_format_cb),\n \t\tOPT_BOOL(0, \"all\", &all_keys, N_(\"print all keys/values\")),\n+\t\tOPT_BOOL(0, \"keys\", &show_keys, N_(\"show keys\")),\n \t\tOPT_END()\n \t};\n \n \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n \n+\tif (show_keys && (all_keys || argc))\n+\t\tdie(_(\"--keys cannot be used with a <key> or --all\"));\n+\n+\tif (show_keys)\n+\t\treturn print_keys(format);\n+\n \tif (format == FORMAT_DEFAULT)\n \t\tformat = FORMAT_KEYVALUE;\n \ndiff --git a/t/t1900-repo.sh b/t/t1900-repo.sh\nindex e6670f0f58..832938e958 100755\n--- a/t/t1900-repo.sh\n+++ b/t/t1900-repo.sh\n@@ -4,15 +4,6 @@ test_description='test git repo-info'\n \n . ./test-lib.sh\n \n-# git-repo-info keys. It must contain the same keys listed in the const\n-# repo_info_fields, in lexicographical order.\n-REPO_INFO_KEYS='\n-\tlayout.bare\n-\tlayout.shallow\n-\tobject.format\n-\treferences.format\n-'\n-\n # Test whether a key-value pair is correctly returned\n #\n # Usage: test_repo_info <label> <init command> <repo_name> <key> <expected value>\n@@ -119,8 +110,8 @@ test_expect_success 'git repo info uses the last requested format' '\n \ttest_cmp expected actual\n '\n \n-test_expect_success 'git repo info --all returns all key-value pairs' '\n-\tgit repo info $REPO_INFO_KEYS >expect &&\n+test_expect_success 'git repo info --all and git repo info $(git repo info --keys) output the same data' '\n+\tgit repo info $(git repo info --keys) >expect &&\n \tgit repo info --all >actual &&\n \ttest_cmp expect actual\n '\n@@ -143,4 +134,33 @@ test_expect_success '--format=default resets the format' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'git repo info --keys --format=nul uses nul-terminated output' '\n+\tgit repo info --keys --format=default >default &&\n+\tlf_to_nul <default >expect &&\n+\tgit repo info --keys --format=nul >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git repo info --keys aborts when using --format other than default or nul' '\n+\techo \"fatal: --keys can only be used with --format=default or --format=nul\" >expect &&\n+\ttest_must_fail git repo info --keys --format=keyvalue 2>actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git repo info --keys aborts when requesting keys' '\n+\techo \"fatal: --keys cannot be used with a <key> or --all\" >expect &&\n+\ttest_must_fail git repo info --keys --all 2>actual_all &&\n+\ttest_must_fail git repo info --keys some.key 2>actual_key &&\n+\ttest_cmp expect actual_all &&\n+\ttest_cmp expect actual_key\n+'\n+\n+test_expect_success 'git repo info --keys uses lines as its default output format' '\n+\tgit repo info --keys --format=lines >expect &&\n+\tgit repo info --keys --format=default >actual_explicit &&\n+\tgit repo info --keys >actual_implicit &&\n+\ttest_cmp expect actual_explicit &&\n+\ttest_cmp expect actual_implicit\n+'\n+\n test_done\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"534202","messageId":"xmqq4ioh3y1w.fsf@gitster.g","threadId":"64592","inReplyTo":"20260119210932.68893-1-lucasseikioshiro@gmail.com","subject":"Re: [PATCH v4 0/2] repo: add --format=default and --keys","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-01-20T00:52:43Z","receivedAt":"2026-01-20T00:52:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lucas Seiki Oshiro <lucasseikioshiro@gmail.com> writes:\n\n> Hello, again!\n>\n> This v4 addresses these two issues:\n>\n> 1. NUL was replaced by _NUL_ in the documentation\n> 2. Now, the default output format of `git repo info --keys` is \"lines\"\n>    and \"default\" is a synonym for it. I prefer to called it \"lines\"\n>    instead of \"newline\" (as suggested by Patrick) because I thought that\n>    it would be clear to the user\n\nSounds good.  It feels natural to ask for \"newline-delimited\" output\nformat by telling the tool \"give me lines\".\n\n"},{"id":"534211","messageId":"aW8bOfVLcG58t-Uk@pks.im","threadId":"64592","inReplyTo":"20260119210932.68893-3-lucasseikioshiro@gmail.com","subject":"Re: [PATCH v4 2/2] repo: add new flag --keys to git-repo-info","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-01-20T06:05:45Z","receivedAt":"2026-01-20T06:05:55Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Jan 19, 2026 at 05:20:20PM -0300, Lucas Seiki Oshiro wrote:\n> diff --git a/builtin/repo.c b/builtin/repo.c\n> index 306d3fa2df..2f698c5253 100644\n> --- a/builtin/repo.c\n> +++ b/builtin/repo.c\n> @@ -29,6 +30,7 @@ enum output_format {\n>  \tFORMAT_TABLE,\n>  \tFORMAT_KEYVALUE,\n>  \tFORMAT_NUL_TERMINATED,\n> +\tFORMAT_LINES\n>  };\n>  \n>  struct field {\n\nTiny nit: we also tend to terminate the last enum value with a comma.\nThe reason here is that it makes it easier to add new values going\nforward while only having to change one line.\n\n> @@ -149,6 +151,32 @@ static int print_all_fields(struct repository *repo,\n>  \treturn 0;\n>  }\n>  \n> +static int print_keys(enum output_format format)\n> +{\n> +\tchar sep;\n> +\n> +\tif (format == FORMAT_DEFAULT)\n> +\t\tformat = FORMAT_LINES;\n> +\n> +\tswitch (format) {\n> +\tcase FORMAT_LINES:\n> +\t\tsep = '\\n';\n> +\t\tbreak;\n> +\tcase FORMAT_NUL_TERMINATED:\n> +\t\tsep = '\\0';\n> +\t\tbreak;\n> +\tdefault:\n> +\t\tdie(_(\"--keys can only be used with --format=default or --format=nul\"));\n\nThis error message isn't true anymore, as we also support\n\"--format=lines\" now.\n\n> @@ -162,6 +190,8 @@ static int parse_format_cb(const struct option *opt,\n>  \t\t*format = FORMAT_KEYVALUE;\n>  \telse if (!strcmp(arg, \"table\"))\n>  \t\t*format = FORMAT_TABLE;\n> +\telse if (!strcmp(arg, \"lines\"))\n> +\t\t*format = FORMAT_LINES;\n>  \telse if (!strcmp(arg, \"default\"))\n>  \t\t*format = FORMAT_DEFAULT;\n>  \telse\n\nYou also have to adapt `cmd_repo_structure()` to handle this new vaule.\nOtherwise it would `BUG()`. I guess the most reasonable change here\nwould be to treat \"lines\" and \"keyvalue\" as equivalent?\n\nThanks!\n\nPatrick\n"},{"id":"534305","messageId":"2B17A803-F1E0-4A9D-B0B7-2C62DA3939A2@gmail.com","threadId":"64592","inReplyTo":"aW8bOfVLcG58t-Uk@pks.im","subject":"Re: [PATCH v4 2/2] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-20T23:11:35Z","receivedAt":"2026-01-20T23:11:50Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"\n> Tiny nit: we also tend to terminate the last enum value with a comma.\n> The reason here is that it makes it easier to add new values going\n> forward while only having to change one line.\n\nSure, I forgot to add it. \n\n> You also have to adapt `cmd_repo_structure()` to handle this new vaule.\n> Otherwise it would `BUG()`. I guess the most reasonable change here\n> would be to treat \"lines\" and \"keyvalue\" as equivalent?\n\nNice catch! I don't know if it makes sense. If we change that in\nstructure, we'll also need to also change in info, making the name\n\"keyvalue\" useless. Another solution: change the current \"keyvalues\" by\n\"lines\" in those three cases. Maybe it makes more sense than the name\n\"keyvalue\".\n\n> Thanks!\n\nThanks again, Patrick!\n\n"},{"id":"534314","messageId":"aXB9976b3Oqf-_Tp@pks.im","threadId":"64592","inReplyTo":"2B17A803-F1E0-4A9D-B0B7-2C62DA3939A2@gmail.com","subject":"Re: [PATCH v4 2/2] repo: add new flag --keys to git-repo-info","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-01-21T07:19:19Z","receivedAt":"2026-01-21T07:19:29Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Jan 20, 2026 at 08:11:35PM -0300, Lucas Seiki Oshiro wrote:\n> \n> > Tiny nit: we also tend to terminate the last enum value with a comma.\n> > The reason here is that it makes it easier to add new values going\n> > forward while only having to change one line.\n> \n> Sure, I forgot to add it. \n> \n> > You also have to adapt `cmd_repo_structure()` to handle this new vaule.\n> > Otherwise it would `BUG()`. I guess the most reasonable change here\n> > would be to treat \"lines\" and \"keyvalue\" as equivalent?\n> \n> Nice catch! I don't know if it makes sense. If we change that in\n> structure, we'll also need to also change in info, making the name\n> \"keyvalue\" useless. Another solution: change the current \"keyvalues\" by\n> \"lines\" in those three cases. Maybe it makes more sense than the name\n> \"keyvalue\".\n\nI also thought about it, but didn't want to propose it myself. But I\nagree that this would be a reasonable change. After all, git-repo(1) is\nstill young and it's marked as experimental, so from my perspective it\nis fair to do adjustments like this once we notice that we've been a bit\ntoo narrow-minded.\n\nSo I'm all for it.\n\nThanks!\n\nPatrick\n"},{"id":"534351","messageId":"E8095CC7-E913-4012-8036-DD2FC5A0E290@gmail.com","threadId":"64592","inReplyTo":"aXB9976b3Oqf-_Tp@pks.im","subject":"Re: [PATCH v4 2/2] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-21T14:38:13Z","receivedAt":"2026-01-21T14:38:28Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"\n> I also thought about it, but didn't want to propose it myself. But I\n> agree that this would be a reasonable change. After all, git-repo(1) is\n> still young and it's marked as experimental, so from my perspective it\n> is fair to do adjustments like this once we notice that we've been a bit\n> too narrow-minded.\n> \n> So I'm all for it.\n\nAgreed. And I think that it makes more sense than adding a new output\nformat only for --keys and extra checks in other places.\n\nBesides this, I sent first patch of this series (the \"default\" output\nformat) to support -z with --keys [1]. If we change \"keyvalue\" to\n\"lines\" maybe it wouldn't be useful.\n\nSo, now I'm thinking about dropping the first patch and replacing it \nby a new one renaming \"keyvalue\" to \"lines\".\n\n\n[1] https://lore.kernel.org/git/5A4D4433-FD38-4BB0-81B6-3BAD33A30A74@gmail.com/"},{"id":"534559","messageId":"20260123164900.35092-1-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20251207190532.67107-1-lucasseikioshiro@gmail.com","subject":"[PATCH v5 0/2] repo: add --keys and rename \"keyvalue\" to \"lines\"","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-23T16:34:52Z","receivedAt":"2026-01-23T16:49:15Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"Hi!\n\nThere are two main changes in this v5:\n\n- the \"keyvalue\" output format of git-repo-info and git-repo-structure were\n  both renamed by \"lines\"\n- the \"default\" output format was dropped\n\nThis way:\n\n- `git repo info` accepts --format=lines and --format=nul\n- `git repo info --keys` accepts --format=lines and --format=nul\n- `git repo structure` accepts --format=table, --format=lines and --format=nul\n\nLucas Seiki Oshiro (2):\n  repo: rename \"keyvalue\" to \"lines\"\n  repo: add new flag --keys to git-repo-info\n\n Documentation/git-repo.adoc | 32 +++++++++++++++--------\n builtin/repo.c              | 51 ++++++++++++++++++++++++++++++-------\n t/t1900-repo.sh             | 44 ++++++++++++++++++++++----------\n t/t1901-repo-structure.sh   |  4 +--\n 4 files changed, 97 insertions(+), 34 deletions(-)\n\nRange-diff against v4:\n1:  7dabd62250 < -:  ---------- repo: add a default output format to enum output_format\n-:  ---------- > 1:  f5448ce915 repo: rename \"keyvalue\" to \"lines\"\n2:  fba621fc4f ! 2:  16bc72afe1 repo: add new flag --keys to git-repo-info\n    @@ Documentation/git-repo.adoc\n     @@ Documentation/git-repo.adoc: SYNOPSIS\n      --------\n      [synopsis]\n    - git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\n    -+git repo info --keys [--format=(default|lines|nul) | -z]\n    - git repo structure [--format=(default|table|keyvalue|nul) | -z]\n    + git repo info [--format=(lines|nul) | -z] [--all | <key>...]\n    ++git repo info --keys [--format=(lines|nul) | -z]\n    + git repo structure [--format=(table|lines|nul) | -z]\n\n      DESCRIPTION\n     @@ Documentation/git-repo.adoc: supported:\n      +\n      `-z` is an alias for `--format=nul`.\n\n    -+`info --keys [--format=(default|lines|nul) | -z]`::\n    ++`info --keys [--format=(lines|nul) | -z]`::\n     +\tList all the available keys, one per line. The output format can be chosen\n     +\tthrough the flag `--format`. The following formats are supported:\n     ++\n    -+`default`:::\n    -+\tsynonym for `lines`.\n    -+\n     +`lines`:::\n    -+\toutput the keys one per line.\n    ++\toutput the keys one per line. This is the default.\n     +\n     +`nul`:::\n    -+\tsimilar to `default`, but using a _NUL_ character after each value.\n    ++\tsimilar to `lines`, but using a _NUL_ character after each value.\n     +\n    - `structure [--format=(default|table|keyvalue|nul) | -z]`::\n    + `structure [--format=(table|lines|nul) | -z]`::\n      \tRetrieve statistics about the current repository structure. The\n      \tfollowing kinds of information are reported:\n\n    @@ builtin/repo.c\n     @@\n\n      static const char *const repo_usage[] = {\n    - \t\"git repo info [--format=(default|keyvalue|nul) | -z] [--all | <key>...]\",\n    -+\t\"git repo info --keys [--format=(default|lines|nul) | -z]\",\n    - \t\"git repo structure [--format=(default|table|keyvalue|nul) | -z]\",\n    + \t\"git repo info [--format=(lines|nul) | -z] [--all | <key>...]\",\n    ++\t\"git repo info --keys [--format=(lines|nul) | -z]\",\n    + \t\"git repo structure [--format=(table|lines|nul) | -z]\",\n      \tNULL\n      };\n    -@@ builtin/repo.c: enum output_format {\n    - \tFORMAT_TABLE,\n    - \tFORMAT_KEYVALUE,\n    - \tFORMAT_NUL_TERMINATED,\n    -+\tFORMAT_LINES\n    - };\n    -\n    - struct field {\n     @@ builtin/repo.c: static int print_all_fields(struct repository *repo,\n      \treturn 0;\n      }\n    @@ builtin/repo.c: static int print_all_fields(struct repository *repo,\n     +{\n     +\tchar sep;\n     +\n    -+\tif (format == FORMAT_DEFAULT)\n    -+\t\tformat = FORMAT_LINES;\n    -+\n     +\tswitch (format) {\n     +\tcase FORMAT_LINES:\n     +\t\tsep = '\\n';\n    @@ builtin/repo.c: static int print_all_fields(struct repository *repo,\n     +\t\tsep = '\\0';\n     +\t\tbreak;\n     +\tdefault:\n    -+\t\tdie(_(\"--keys can only be used with --format=default or --format=nul\"));\n    ++\t\tdie(_(\"--keys can only be used with --format=lines or --format=nul\"));\n     +\t}\n     +\n     +\tfor (size_t i = 0; i < ARRAY_SIZE(repo_info_fields); i++) {\n    @@ builtin/repo.c: static int print_all_fields(struct repository *repo,\n      static int parse_format_cb(const struct option *opt,\n      \t\t\t   const char *arg, int unset UNUSED)\n      {\n    -@@ builtin/repo.c: static int parse_format_cb(const struct option *opt,\n    - \t\t*format = FORMAT_KEYVALUE;\n    - \telse if (!strcmp(arg, \"table\"))\n    - \t\t*format = FORMAT_TABLE;\n    -+\telse if (!strcmp(arg, \"lines\"))\n    -+\t\t*format = FORMAT_LINES;\n    - \telse if (!strcmp(arg, \"default\"))\n    - \t\t*format = FORMAT_DEFAULT;\n    - \telse\n     @@ builtin/repo.c: static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n      {\n    - \tenum output_format format = FORMAT_DEFAULT;\n    + \tenum output_format format = FORMAT_LINES;\n      \tint all_keys = 0;\n     +\tint show_keys = 0;\n      \tstruct option options[] = {\n    @@ builtin/repo.c: static int cmd_repo_info(int argc, const char **argv, const char\n     +\tif (show_keys)\n     +\t\treturn print_keys(format);\n     +\n    - \tif (format == FORMAT_DEFAULT)\n    - \t\tformat = FORMAT_KEYVALUE;\n    + \tif (format != FORMAT_LINES && format != FORMAT_NUL_TERMINATED)\n    + \t\tdie(_(\"unsupported output format\"));\n\n\n      ## t/t1900-repo.sh ##\n    @@ t/t1900-repo.sh: test_expect_success 'git repo info uses the last requested form\n      \tgit repo info --all >actual &&\n      \ttest_cmp expect actual\n      '\n    -@@ t/t1900-repo.sh: test_expect_success '--format=default resets the format' '\n    +@@ t/t1900-repo.sh: test_expect_success 'git repo info --all <key> aborts' '\n      \ttest_cmp expect actual\n      '\n\n     +test_expect_success 'git repo info --keys --format=nul uses nul-terminated output' '\n    -+\tgit repo info --keys --format=default >default &&\n    -+\tlf_to_nul <default >expect &&\n    ++\tgit repo info --keys --format=lines >lines &&\n    ++\tlf_to_nul <lines >expect &&\n     +\tgit repo info --keys --format=nul >actual &&\n     +\ttest_cmp expect actual\n     +'\n     +\n    -+test_expect_success 'git repo info --keys aborts when using --format other than default or nul' '\n    -+\techo \"fatal: --keys can only be used with --format=default or --format=nul\" >expect &&\n    -+\ttest_must_fail git repo info --keys --format=keyvalue 2>actual &&\n    ++test_expect_success 'git repo info --keys aborts when using --format other than lines or nul' '\n    ++\techo \"fatal: --keys can only be used with --format=lines or --format=nul\" >expect &&\n    ++\ttest_must_fail git repo info --keys --format=table 2>actual &&\n     +\ttest_cmp expect actual\n     +'\n     +\n    @@ t/t1900-repo.sh: test_expect_success '--format=default resets the format' '\n     +\n     +test_expect_success 'git repo info --keys uses lines as its default output format' '\n     +\tgit repo info --keys --format=lines >expect &&\n    -+\tgit repo info --keys --format=default >actual_explicit &&\n    -+\tgit repo info --keys >actual_implicit &&\n    -+\ttest_cmp expect actual_explicit &&\n    -+\ttest_cmp expect actual_implicit\n    ++\tgit repo info --keys >actual &&\n    ++\ttest_cmp expect actual\n     +'\n     +\n      test_done\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"534560","messageId":"20260123164900.35092-2-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20260123164900.35092-1-lucasseikioshiro@gmail.com","subject":"[PATCH v5 1/2] repo: rename \"keyvalue\" to \"lines\"","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-23T16:34:53Z","receivedAt":"2026-01-23T16:49:20Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"The output format name \"keyvalue\" isn't so descriptive. Rename it to\n\"lines\", since it describes better the syntax of the output format and\nit isn't tied to key-value pairs.\n\nSigned-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n---\n Documentation/git-repo.adoc | 21 +++++++++++----------\n builtin/repo.c              | 19 ++++++++++---------\n t/t1900-repo.sh             |  4 ++--\n t/t1901-repo-structure.sh   |  4 ++--\n 4 files changed, 25 insertions(+), 23 deletions(-)\n\ndiff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\nindex 7d70270dfa..693e1bbced 100644\n--- a/Documentation/git-repo.adoc\n+++ b/Documentation/git-repo.adoc\n@@ -8,8 +8,8 @@ git-repo - Retrieve information about the repository\n SYNOPSIS\n --------\n [synopsis]\n-git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\n-git repo structure [--format=(table|keyvalue|nul) | -z]\n+git repo info [--format=(lines|nul) | -z] [--all | <key>...]\n+git repo structure [--format=(table|lines|nul) | -z]\n \n DESCRIPTION\n -----------\n@@ -19,7 +19,7 @@ THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.\n \n COMMANDS\n --------\n-`info [--format=(keyvalue|nul) | -z] [--all | <key>...]`::\n+`info [--format=(lines|nul) | -z] [--all | <key>...]`::\n \tRetrieve metadata-related information about the current repository. Only\n \tthe requested data will be returned based on their keys (see \"INFO KEYS\"\n \tsection below).\n@@ -30,21 +30,22 @@ requested. The `--all` flag requests the values for all the available keys.\n The output format can be chosen through the flag `--format`. Two formats are\n supported:\n +\n-`keyvalue`:::\n+\n+`lines`:::\n \toutput key-value pairs one per line using the `=` character as\n \tthe delimiter between the key and the value. Values containing \"unusual\"\n \tcharacters are quoted as explained for the configuration variable\n \t`core.quotePath` (see linkgit:git-config[1]). This is the default.\n \n `nul`:::\n-\tsimilar to `keyvalue`, but using a newline character as the delimiter\n+\tsimilar to `lines`, but using a newline character as the delimiter\n \tbetween the key and the value and using a NUL character after each value.\n \tThis format is better suited for being parsed by another applications than\n-\t`keyvalue`. Unlike in the `keyvalue` format, the values are never quoted.\n+\t`lines`. Unlike in the `lines` format, the values are never quoted.\n +\n `-z` is an alias for `--format=nul`.\n \n-`structure [--format=(table|keyvalue|nul) | -z]`::\n+`structure [--format=(table|lines|nul) | -z]`::\n \tRetrieve statistics about the current repository structure. The\n \tfollowing kinds of information are reported:\n +\n@@ -61,17 +62,17 @@ supported:\n \tchange and is not intended for machine parsing. This is the default\n \tformat.\n \n-`keyvalue`:::\n+`lines`:::\n \tEach line of output contains a key-value pair for a repository stat.\n \tThe '=' character is used to delimit between the key and the value.\n \tValues containing \"unusual\" characters are quoted as explained for the\n \tconfiguration variable `core.quotePath` (see linkgit:git-config[1]).\n \n `nul`:::\n-\tSimilar to `keyvalue`, but uses a NUL character to delimit between\n+\tSimilar to `lines`, but uses a NUL character to delimit between\n \tkey-value pairs instead of a newline. Also uses a newline character as\n \tthe delimiter between the key and value instead of '='. Unlike the\n-\t`keyvalue` format, values containing \"unusual\" characters are never\n+\t`lines` format, values containing \"unusual\" characters are never\n \tquoted.\n +\n `-z` is an alias for `--format=nul`.\ndiff --git a/builtin/repo.c b/builtin/repo.c\nindex 0ea045abc1..4031612bc8 100644\n--- a/builtin/repo.c\n+++ b/builtin/repo.c\n@@ -17,8 +17,8 @@\n #include \"utf8.h\"\n \n static const char *const repo_usage[] = {\n-\t\"git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\",\n-\t\"git repo structure [--format=(table|keyvalue|nul) | -z]\",\n+\t\"git repo info [--format=(lines|nul) | -z] [--all | <key>...]\",\n+\t\"git repo structure [--format=(table|lines|nul) | -z]\",\n \tNULL\n };\n \n@@ -26,7 +26,7 @@ typedef int get_value_fn(struct repository *repo, struct strbuf *buf);\n \n enum output_format {\n \tFORMAT_TABLE,\n-\tFORMAT_KEYVALUE,\n+\tFORMAT_LINES,\n \tFORMAT_NUL_TERMINATED,\n };\n \n@@ -91,7 +91,7 @@ static void print_field(enum output_format format, const char *key,\n \t\t\tconst char *value)\n {\n \tswitch (format) {\n-\tcase FORMAT_KEYVALUE:\n+\tcase FORMAT_LINES:\n \t\tprintf(\"%s=\", key);\n \t\tquote_c_style(value, NULL, stdout, 0);\n \t\tputchar('\\n');\n@@ -157,8 +157,8 @@ static int parse_format_cb(const struct option *opt,\n \t\t*format = FORMAT_NUL_TERMINATED;\n \telse if (!strcmp(arg, \"nul\"))\n \t\t*format = FORMAT_NUL_TERMINATED;\n-\telse if (!strcmp(arg, \"keyvalue\"))\n-\t\t*format = FORMAT_KEYVALUE;\n+\telse if (!strcmp(arg, \"lines\"))\n+\t\t*format = FORMAT_LINES;\n \telse if (!strcmp(arg, \"table\"))\n \t\t*format = FORMAT_TABLE;\n \telse\n@@ -170,7 +170,7 @@ static int parse_format_cb(const struct option *opt,\n static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t\t\t struct repository *repo)\n {\n-\tenum output_format format = FORMAT_KEYVALUE;\n+\tenum output_format format = FORMAT_LINES;\n \tint all_keys = 0;\n \tstruct option options[] = {\n \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n@@ -185,7 +185,8 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t};\n \n \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n-\tif (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED)\n+\n+\tif (format != FORMAT_LINES && format != FORMAT_NUL_TERMINATED)\n \t\tdie(_(\"unsupported output format\"));\n \n \tif (all_keys && argc)\n@@ -671,7 +672,7 @@ static int cmd_repo_structure(int argc, const char **argv, const char *prefix,\n \t\tstats_table_setup_structure(&table, &stats);\n \t\tstats_table_print_structure(&table);\n \t\tbreak;\n-\tcase FORMAT_KEYVALUE:\n+\tcase FORMAT_LINES:\n \t\tstructure_keyvalue_print(&stats, '=', '\\n');\n \t\tbreak;\n \tcase FORMAT_NUL_TERMINATED:\ndiff --git a/t/t1900-repo.sh b/t/t1900-repo.sh\nindex 51d55f11a5..4155211e5d 100755\n--- a/t/t1900-repo.sh\n+++ b/t/t1900-repo.sh\n@@ -34,7 +34,7 @@ test_repo_info () {\n \t\teval \"$init_command $repo_name\"\n \t'\n \n-\ttest_expect_success \"keyvalue: $label\" '\n+\ttest_expect_success \"lines: $label\" '\n \t\techo \"$key=$expected_value\" > expect &&\n \t\tgit -C \"$repo_name\" repo info \"$key\" >actual &&\n \t\ttest_cmp expect actual\n@@ -115,7 +115,7 @@ test_expect_success '-z uses nul-terminated format' '\n \n test_expect_success 'git repo info uses the last requested format' '\n \techo \"layout.bare=false\" >expected &&\n-\tgit repo info --format=nul -z --format=keyvalue layout.bare >actual &&\n+\tgit repo info --format=nul -z --format=lines layout.bare >actual &&\n \ttest_cmp expected actual\n '\n \ndiff --git a/t/t1901-repo-structure.sh b/t/t1901-repo-structure.sh\nindex 17ff164b05..a6f2591d9a 100755\n--- a/t/t1901-repo-structure.sh\n+++ b/t/t1901-repo-structure.sh\n@@ -113,7 +113,7 @@ test_expect_success SHA1 'repository with references and objects' '\n \t)\n '\n \n-test_expect_success SHA1 'keyvalue and nul format' '\n+test_expect_success SHA1 'lines and nul format' '\n \ttest_when_finished \"rm -rf repo\" &&\n \tgit init repo &&\n \t(\n@@ -140,7 +140,7 @@ test_expect_success SHA1 'keyvalue and nul format' '\n \t\tobjects.tags.disk_size=$(object_type_disk_usage tag)\n \t\tEOF\n \n-\t\tgit repo structure --format=keyvalue >out 2>err &&\n+\t\tgit repo structure --format=lines >out 2>err &&\n \n \t\ttest_cmp expect out &&\n \t\ttest_line_count = 0 err &&\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"534561","messageId":"20260123164900.35092-3-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20260123164900.35092-1-lucasseikioshiro@gmail.com","subject":"[PATCH v5 2/2] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-23T16:34:54Z","receivedAt":"2026-01-23T16:49:22Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"If the user wants to find what are the available keys, they need to\neither check the documentation or to ask for all the key-value pairs\nby using --all.\n\nAdd a new flag --keys for listing only the available keys without\nlisting the values.\n\nSigned-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n---\n Documentation/git-repo.adoc | 11 ++++++++++\n builtin/repo.c              | 32 +++++++++++++++++++++++++++++\n t/t1900-repo.sh             | 40 +++++++++++++++++++++++++++----------\n 3 files changed, 72 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\nindex 693e1bbced..f474274009 100644\n--- a/Documentation/git-repo.adoc\n+++ b/Documentation/git-repo.adoc\n@@ -9,6 +9,7 @@ SYNOPSIS\n --------\n [synopsis]\n git repo info [--format=(lines|nul) | -z] [--all | <key>...]\n+git repo info --keys [--format=(lines|nul) | -z]\n git repo structure [--format=(table|lines|nul) | -z]\n \n DESCRIPTION\n@@ -45,6 +46,16 @@ supported:\n +\n `-z` is an alias for `--format=nul`.\n \n+`info --keys [--format=(lines|nul) | -z]`::\n+\tList all the available keys, one per line. The output format can be chosen\n+\tthrough the flag `--format`. The following formats are supported:\n++\n+`lines`:::\n+\toutput the keys one per line. This is the default.\n+\n+`nul`:::\n+\tsimilar to `lines`, but using a _NUL_ character after each value.\n+\n `structure [--format=(table|lines|nul) | -z]`::\n \tRetrieve statistics about the current repository structure. The\n \tfollowing kinds of information are reported:\ndiff --git a/builtin/repo.c b/builtin/repo.c\nindex 4031612bc8..a7d4855f06 100644\n--- a/builtin/repo.c\n+++ b/builtin/repo.c\n@@ -18,6 +18,7 @@\n \n static const char *const repo_usage[] = {\n \t\"git repo info [--format=(lines|nul) | -z] [--all | <key>...]\",\n+\t\"git repo info --keys [--format=(lines|nul) | -z]\",\n \t\"git repo structure [--format=(table|lines|nul) | -z]\",\n \tNULL\n };\n@@ -148,6 +149,29 @@ static int print_all_fields(struct repository *repo,\n \treturn 0;\n }\n \n+static int print_keys(enum output_format format)\n+{\n+\tchar sep;\n+\n+\tswitch (format) {\n+\tcase FORMAT_LINES:\n+\t\tsep = '\\n';\n+\t\tbreak;\n+\tcase FORMAT_NUL_TERMINATED:\n+\t\tsep = '\\0';\n+\t\tbreak;\n+\tdefault:\n+\t\tdie(_(\"--keys can only be used with --format=lines or --format=nul\"));\n+\t}\n+\n+\tfor (size_t i = 0; i < ARRAY_SIZE(repo_info_fields); i++) {\n+\t\tconst struct field *field = &repo_info_fields[i];\n+\t\tprintf(\"%s%c\", field->key, sep);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int parse_format_cb(const struct option *opt,\n \t\t\t   const char *arg, int unset UNUSED)\n {\n@@ -172,6 +196,7 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n {\n \tenum output_format format = FORMAT_LINES;\n \tint all_keys = 0;\n+\tint show_keys = 0;\n \tstruct option options[] = {\n \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n \t\t\t       N_(\"output format\"),\n@@ -181,11 +206,18 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t\t\t       PARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\t       parse_format_cb),\n \t\tOPT_BOOL(0, \"all\", &all_keys, N_(\"print all keys/values\")),\n+\t\tOPT_BOOL(0, \"keys\", &show_keys, N_(\"show keys\")),\n \t\tOPT_END()\n \t};\n \n \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n \n+\tif (show_keys && (all_keys || argc))\n+\t\tdie(_(\"--keys cannot be used with a <key> or --all\"));\n+\n+\tif (show_keys)\n+\t\treturn print_keys(format);\n+\n \tif (format != FORMAT_LINES && format != FORMAT_NUL_TERMINATED)\n \t\tdie(_(\"unsupported output format\"));\n \ndiff --git a/t/t1900-repo.sh b/t/t1900-repo.sh\nindex 4155211e5d..a9eb07abe8 100755\n--- a/t/t1900-repo.sh\n+++ b/t/t1900-repo.sh\n@@ -4,15 +4,6 @@ test_description='test git repo-info'\n \n . ./test-lib.sh\n \n-# git-repo-info keys. It must contain the same keys listed in the const\n-# repo_info_fields, in lexicographical order.\n-REPO_INFO_KEYS='\n-\tlayout.bare\n-\tlayout.shallow\n-\tobject.format\n-\treferences.format\n-'\n-\n # Test whether a key-value pair is correctly returned\n #\n # Usage: test_repo_info <label> <init command> <repo_name> <key> <expected value>\n@@ -119,8 +110,8 @@ test_expect_success 'git repo info uses the last requested format' '\n \ttest_cmp expected actual\n '\n \n-test_expect_success 'git repo info --all returns all key-value pairs' '\n-\tgit repo info $REPO_INFO_KEYS >expect &&\n+test_expect_success 'git repo info --all and git repo info $(git repo info --keys) output the same data' '\n+\tgit repo info $(git repo info --keys) >expect &&\n \tgit repo info --all >actual &&\n \ttest_cmp expect actual\n '\n@@ -131,4 +122,31 @@ test_expect_success 'git repo info --all <key> aborts' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'git repo info --keys --format=nul uses nul-terminated output' '\n+\tgit repo info --keys --format=lines >lines &&\n+\tlf_to_nul <lines >expect &&\n+\tgit repo info --keys --format=nul >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git repo info --keys aborts when using --format other than lines or nul' '\n+\techo \"fatal: --keys can only be used with --format=lines or --format=nul\" >expect &&\n+\ttest_must_fail git repo info --keys --format=table 2>actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git repo info --keys aborts when requesting keys' '\n+\techo \"fatal: --keys cannot be used with a <key> or --all\" >expect &&\n+\ttest_must_fail git repo info --keys --all 2>actual_all &&\n+\ttest_must_fail git repo info --keys some.key 2>actual_key &&\n+\ttest_cmp expect actual_all &&\n+\ttest_cmp expect actual_key\n+'\n+\n+test_expect_success 'git repo info --keys uses lines as its default output format' '\n+\tgit repo info --keys --format=lines >expect &&\n+\tgit repo info --keys >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"534701","messageId":"aXhiHAFNFxgsXa0S@pks.im","threadId":"64592","inReplyTo":"20260123164900.35092-2-lucasseikioshiro@gmail.com","subject":"Re: [PATCH v5 1/2] repo: rename \"keyvalue\" to \"lines\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-01-27T06:58:36Z","receivedAt":"2026-01-27T06:58:42Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Fri, Jan 23, 2026 at 01:34:53PM -0300, Lucas Seiki Oshiro wrote:\n> The output format name \"keyvalue\" isn't so descriptive. Rename it to\n> \"lines\", since it describes better the syntax of the output format and\n> it isn't tied to key-value pairs.\n\nI think this commit message is a bit hand-wavy. Most importantly, the\nreader might wonder _why_ it isn't so descriptive, and why these\nconcerns are strong enough to change the accepted value now.\n\nI would've written something like the following:\n\n    Both subcommands in git-repo(1) accept the \"keyvalue\" format. This\n    format is newline-delimited, where the key is separated from the\n    value with an equals sign.\n\n    The name of this option is suboptimal though, as it is both too\n    limiting while at the same time not really indicating what it\n    actually does:\n\n      - There is no mention of the format being newline-delimited, which\n        is the key differentiator to the \"nul\" format.\n\n      - Both \"nul\" and \"keyvalue\" have a key and a value, so the latter\n        is not exactly giving any hint what makes it so special.\n\n      - \"keyvalue\" requires there to be, well, a key and a value, but we\n        want to add additional output that is only going to be newline\n        delimited.\n\n    Taken together, \"keyvalue\" is kind of a bad name for this output\n    format.\n\n    Luckily, the git-repo(1) command is still rather new and marked as\n    experimental, so things aren't cast into stone yet. Rename the\n    format to \"lines\" instead to better indicate that the major\n    difference is that we'll get newline-delimited output. This new name\n    will also be a better fit for a subsequent extension in git-repo(1).\n\nPlease feel free to use this message or parts of it if you plan to\nreroll.\n\nI was also briefly wondering whether it would make sense to call the new\nformat \"newlines\" instead of \"lines\", but I'm not feeling strongly about\nthis in any way.\n\n> diff --git a/builtin/repo.c b/builtin/repo.c\n> index 0ea045abc1..4031612bc8 100644\n> --- a/builtin/repo.c\n> +++ b/builtin/repo.c\n> @@ -26,7 +26,7 @@ typedef int get_value_fn(struct repository *repo, struct strbuf *buf);\n>  \n>  enum output_format {\n>  \tFORMAT_TABLE,\n> -\tFORMAT_KEYVALUE,\n> +\tFORMAT_LINES,\n>  \tFORMAT_NUL_TERMINATED,\n>  };\n\nThis feels a bit unbalanced to me, as `FORMAT_LINES` and\n`FORMAT_NUL_TERMINATED` look so different from one another. Maybe it\nwould be better to call it `FORMAT_NEWLINE_TERMINATED`?\n\nPatrick\n"},{"id":"534702","messageId":"aXhiIQXBvMhzkFy9@pks.im","threadId":"64592","inReplyTo":"20260123164900.35092-3-lucasseikioshiro@gmail.com","subject":"Re: [PATCH v5 2/2] repo: add new flag --keys to git-repo-info","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-01-27T06:58:41Z","receivedAt":"2026-01-27T06:58:46Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Fri, Jan 23, 2026 at 01:34:54PM -0300, Lucas Seiki Oshiro wrote:\n> diff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\n> index 693e1bbced..f474274009 100644\n> --- a/Documentation/git-repo.adoc\n> +++ b/Documentation/git-repo.adoc\n> @@ -45,6 +46,16 @@ supported:\n>  +\n>  `-z` is an alias for `--format=nul`.\n>  \n> +`info --keys [--format=(lines|nul) | -z]`::\n> +\tList all the available keys, one per line. The output format can be chosen\n> +\tthrough the flag `--format`. The following formats are supported:\n> ++\n> +`lines`:::\n> +\toutput the keys one per line. This is the default.\n> +\n> +`nul`:::\n> +\tsimilar to `lines`, but using a _NUL_ character after each value.\n\nShouldn' these sentences start with an upper-case character? I see that\nwe don't do it either for the existing docs, but it reads a bit weird to\nme.\n\nPatrick\n"},{"id":"534734","messageId":"F857412A-6B47-4DE0-85BC-D8AC2E54669F@gmail.com","threadId":"64592","inReplyTo":"aXhiIQXBvMhzkFy9@pks.im","subject":"Re: [PATCH v5 2/2] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-01-27T22:27:05Z","receivedAt":"2026-01-27T22:27:21Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"\n>> \n>> +`info --keys [--format=(lines|nul) | -z]`::\n>> + List all the available keys, one per line. The output format can be chosen\n>> + through the flag `--format`. The following formats are supported:\n>> ++\n>> +`lines`:::\n>> + output the keys one per line. This is the default.\n>> +\n>> +`nul`:::\n>> + similar to `lines`, but using a _NUL_ character after each value.\n> \n> Shouldn' these sentences start with an upper-case character? I see that\n> we don't do it either for the existing docs, but it reads a bit weird to\n> me.\n\nOk, I'll fix it.\n\nBtw, I'm collecting those nitpicks about the existing code and I'll send\na patch series fixing them after finishing this :-)\n\n"},{"id":"535994","messageId":"20260214005818.37349-1-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20251207190532.67107-1-lucasseikioshiro@gmail.com","subject":"[PATCH v6 0/2] repo: add --keys and rename \"keyvalue\" to \"lines\"","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-02-14T00:35:14Z","receivedAt":"2026-02-14T00:58:30Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"Hi!\n\nThis v6 addresses these issues raised by Patrick:\n\n- It renames `FORMAT_LINES` to `FORMAT_NEWLINE_TERMINATED`\n- Change the commit messsage of the first patch (I'm using Patrick's\n  suggestion)\n- It capitalizes the new paragraphs\n\nThere was a discussion about the name of the new format (\"lines\" vs\n\"newline\") [1]. Personally I prefer \"lines\" instead of \"newline\" because\nI understand the --format flag expects a format name (e.g. `table`,\n`lines`) instead of the delimiter, being `nul` only a short form of\n\"nul-terminated\". But, of course, I'm open to other opinions about it\n:-).\n\nThanks\n\n[1] aXhiHAFNFxgsXa0S@pks.im\n\nLucas Seiki Oshiro (2):\n  repo: rename the output format \"keyvalue\" to \"lines\"\n  repo: add new flag --keys to git-repo-info\n\n Documentation/git-repo.adoc | 32 +++++++++++++++--------\n builtin/repo.c              | 51 ++++++++++++++++++++++++++++++-------\n t/t1900-repo.sh             | 44 ++++++++++++++++++++++----------\n t/t1901-repo-structure.sh   |  4 +--\n 4 files changed, 97 insertions(+), 34 deletions(-)\n\nRange-diff against v5:\n1:  f5448ce915 ! 1:  6f5b4a577e repo: rename \"keyvalue\" to \"lines\"\n    @@ Metadata\n     Author: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n     \n      ## Commit message ##\n    -    repo: rename \"keyvalue\" to \"lines\"\n    +    repo: rename the output format \"keyvalue\" to \"lines\"\n     \n    -    The output format name \"keyvalue\" isn't so descriptive. Rename it to\n    -    \"lines\", since it describes better the syntax of the output format and\n    -    it isn't tied to key-value pairs.\n    +    Both subcommands in git-repo(1) accept the \"keyvalue\" format. This\n    +    format is newline-delimited, where the key is separated from the\n    +    value with an equals sign.\n     \n    +    The name of this option is suboptimal though, as it is both too\n    +    limiting while at the same time not really indicating what it\n    +    actually does:\n    +\n    +      - There is no mention of the format being newline-delimited, which\n    +        is the key differentiator to the \"nul\" format.\n    +\n    +      - Both \"nul\" and \"keyvalue\" have a key and a value, so the latter\n    +        is not exactly giving any hint what makes it so special.\n    +\n    +      - \"keyvalue\" requires there to be, well, a key and a value, but we\n    +        want to add additional output that is only going to be newline\n    +        delimited.\n    +\n    +    Taken together, \"keyvalue\" is kind of a bad name for this output\n    +    format.\n    +\n    +    Luckily, the git-repo(1) command is still rather new and marked as\n    +    experimental, so things aren't cast into stone yet. Rename the\n    +    format to \"lines\" instead to better indicate that the major\n    +    difference is that we'll get newline-delimited output. This new name\n    +    will also be a better fit for a subsequent extension in git-repo(1).\n    +\n    +    Helped-by: Patrick Steinhardt <ps@pks.im>\n         Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n     \n      ## Documentation/git-repo.adoc ##\n    @@ builtin/repo.c: typedef int get_value_fn(struct repository *repo, struct strbuf\n      enum output_format {\n      \tFORMAT_TABLE,\n     -\tFORMAT_KEYVALUE,\n    -+\tFORMAT_LINES,\n    ++\tFORMAT_NEWLINE_TERMINATED,\n      \tFORMAT_NUL_TERMINATED,\n      };\n      \n    @@ builtin/repo.c: static void print_field(enum output_format format, const char *k\n      {\n      \tswitch (format) {\n     -\tcase FORMAT_KEYVALUE:\n    -+\tcase FORMAT_LINES:\n    ++\tcase FORMAT_NEWLINE_TERMINATED:\n      \t\tprintf(\"%s=\", key);\n      \t\tquote_c_style(value, NULL, stdout, 0);\n      \t\tputchar('\\n');\n    @@ builtin/repo.c: static int parse_format_cb(const struct option *opt,\n     -\telse if (!strcmp(arg, \"keyvalue\"))\n     -\t\t*format = FORMAT_KEYVALUE;\n     +\telse if (!strcmp(arg, \"lines\"))\n    -+\t\t*format = FORMAT_LINES;\n    ++\t\t*format = FORMAT_NEWLINE_TERMINATED;\n      \telse if (!strcmp(arg, \"table\"))\n      \t\t*format = FORMAT_TABLE;\n      \telse\n    @@ builtin/repo.c: static int parse_format_cb(const struct option *opt,\n      \t\t\t struct repository *repo)\n      {\n     -\tenum output_format format = FORMAT_KEYVALUE;\n    -+\tenum output_format format = FORMAT_LINES;\n    ++\tenum output_format format = FORMAT_NEWLINE_TERMINATED;\n      \tint all_keys = 0;\n      \tstruct option options[] = {\n      \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n    @@ builtin/repo.c: static int cmd_repo_info(int argc, const char **argv, const char\n      \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n     -\tif (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED)\n     +\n    -+\tif (format != FORMAT_LINES && format != FORMAT_NUL_TERMINATED)\n    ++\tif (format != FORMAT_NEWLINE_TERMINATED && format != FORMAT_NUL_TERMINATED)\n      \t\tdie(_(\"unsupported output format\"));\n      \n      \tif (all_keys && argc)\n    @@ builtin/repo.c: static int cmd_repo_structure(int argc, const char **argv, const\n      \t\tstats_table_print_structure(&table);\n      \t\tbreak;\n     -\tcase FORMAT_KEYVALUE:\n    -+\tcase FORMAT_LINES:\n    ++\tcase FORMAT_NEWLINE_TERMINATED:\n      \t\tstructure_keyvalue_print(&stats, '=', '\\n');\n      \t\tbreak;\n      \tcase FORMAT_NUL_TERMINATED:\n2:  16bc72afe1 ! 2:  53503e1433 repo: add new flag --keys to git-repo-info\n    @@ Documentation/git-repo.adoc: supported:\n     +\tthrough the flag `--format`. The following formats are supported:\n     ++\n     +`lines`:::\n    -+\toutput the keys one per line. This is the default.\n    ++\tOutput the keys one per line. This is the default.\n     +\n     +`nul`:::\n    -+\tsimilar to `lines`, but using a _NUL_ character after each value.\n    ++\tSimilar to `lines`, but using a _NUL_ character after each value.\n     +\n      `structure [--format=(table|lines|nul) | -z]`::\n      \tRetrieve statistics about the current repository structure. The\n    @@ builtin/repo.c: static int print_all_fields(struct repository *repo,\n     +\tchar sep;\n     +\n     +\tswitch (format) {\n    -+\tcase FORMAT_LINES:\n    ++\tcase FORMAT_NEWLINE_TERMINATED:\n     +\t\tsep = '\\n';\n     +\t\tbreak;\n     +\tcase FORMAT_NUL_TERMINATED:\n    @@ builtin/repo.c: static int print_all_fields(struct repository *repo,\n      {\n     @@ builtin/repo.c: static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n      {\n    - \tenum output_format format = FORMAT_LINES;\n    + \tenum output_format format = FORMAT_NEWLINE_TERMINATED;\n      \tint all_keys = 0;\n     +\tint show_keys = 0;\n      \tstruct option options[] = {\n    @@ builtin/repo.c: static int cmd_repo_info(int argc, const char **argv, const char\n     +\tif (show_keys)\n     +\t\treturn print_keys(format);\n     +\n    - \tif (format != FORMAT_LINES && format != FORMAT_NUL_TERMINATED)\n    + \tif (format != FORMAT_NEWLINE_TERMINATED && format != FORMAT_NUL_TERMINATED)\n      \t\tdie(_(\"unsupported output format\"));\n      \n     \n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"535995","messageId":"20260214005818.37349-2-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20260214005818.37349-1-lucasseikioshiro@gmail.com","subject":"[PATCH v6 1/2] repo: rename the output format \"keyvalue\" to \"lines\"","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-02-14T00:35:15Z","receivedAt":"2026-02-14T00:58:33Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"Both subcommands in git-repo(1) accept the \"keyvalue\" format. This\nformat is newline-delimited, where the key is separated from the\nvalue with an equals sign.\n\nThe name of this option is suboptimal though, as it is both too\nlimiting while at the same time not really indicating what it\nactually does:\n\n  - There is no mention of the format being newline-delimited, which\n    is the key differentiator to the \"nul\" format.\n\n  - Both \"nul\" and \"keyvalue\" have a key and a value, so the latter\n    is not exactly giving any hint what makes it so special.\n\n  - \"keyvalue\" requires there to be, well, a key and a value, but we\n    want to add additional output that is only going to be newline\n    delimited.\n\nTaken together, \"keyvalue\" is kind of a bad name for this output\nformat.\n\nLuckily, the git-repo(1) command is still rather new and marked as\nexperimental, so things aren't cast into stone yet. Rename the\nformat to \"lines\" instead to better indicate that the major\ndifference is that we'll get newline-delimited output. This new name\nwill also be a better fit for a subsequent extension in git-repo(1).\n\nHelped-by: Patrick Steinhardt <ps@pks.im>\nSigned-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n---\n Documentation/git-repo.adoc | 21 +++++++++++----------\n builtin/repo.c              | 19 ++++++++++---------\n t/t1900-repo.sh             |  4 ++--\n t/t1901-repo-structure.sh   |  4 ++--\n 4 files changed, 25 insertions(+), 23 deletions(-)\n\ndiff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\nindex 7d70270dfa..693e1bbced 100644\n--- a/Documentation/git-repo.adoc\n+++ b/Documentation/git-repo.adoc\n@@ -8,8 +8,8 @@ git-repo - Retrieve information about the repository\n SYNOPSIS\n --------\n [synopsis]\n-git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\n-git repo structure [--format=(table|keyvalue|nul) | -z]\n+git repo info [--format=(lines|nul) | -z] [--all | <key>...]\n+git repo structure [--format=(table|lines|nul) | -z]\n \n DESCRIPTION\n -----------\n@@ -19,7 +19,7 @@ THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.\n \n COMMANDS\n --------\n-`info [--format=(keyvalue|nul) | -z] [--all | <key>...]`::\n+`info [--format=(lines|nul) | -z] [--all | <key>...]`::\n \tRetrieve metadata-related information about the current repository. Only\n \tthe requested data will be returned based on their keys (see \"INFO KEYS\"\n \tsection below).\n@@ -30,21 +30,22 @@ requested. The `--all` flag requests the values for all the available keys.\n The output format can be chosen through the flag `--format`. Two formats are\n supported:\n +\n-`keyvalue`:::\n+\n+`lines`:::\n \toutput key-value pairs one per line using the `=` character as\n \tthe delimiter between the key and the value. Values containing \"unusual\"\n \tcharacters are quoted as explained for the configuration variable\n \t`core.quotePath` (see linkgit:git-config[1]). This is the default.\n \n `nul`:::\n-\tsimilar to `keyvalue`, but using a newline character as the delimiter\n+\tsimilar to `lines`, but using a newline character as the delimiter\n \tbetween the key and the value and using a NUL character after each value.\n \tThis format is better suited for being parsed by another applications than\n-\t`keyvalue`. Unlike in the `keyvalue` format, the values are never quoted.\n+\t`lines`. Unlike in the `lines` format, the values are never quoted.\n +\n `-z` is an alias for `--format=nul`.\n \n-`structure [--format=(table|keyvalue|nul) | -z]`::\n+`structure [--format=(table|lines|nul) | -z]`::\n \tRetrieve statistics about the current repository structure. The\n \tfollowing kinds of information are reported:\n +\n@@ -61,17 +62,17 @@ supported:\n \tchange and is not intended for machine parsing. This is the default\n \tformat.\n \n-`keyvalue`:::\n+`lines`:::\n \tEach line of output contains a key-value pair for a repository stat.\n \tThe '=' character is used to delimit between the key and the value.\n \tValues containing \"unusual\" characters are quoted as explained for the\n \tconfiguration variable `core.quotePath` (see linkgit:git-config[1]).\n \n `nul`:::\n-\tSimilar to `keyvalue`, but uses a NUL character to delimit between\n+\tSimilar to `lines`, but uses a NUL character to delimit between\n \tkey-value pairs instead of a newline. Also uses a newline character as\n \tthe delimiter between the key and value instead of '='. Unlike the\n-\t`keyvalue` format, values containing \"unusual\" characters are never\n+\t`lines` format, values containing \"unusual\" characters are never\n \tquoted.\n +\n `-z` is an alias for `--format=nul`.\ndiff --git a/builtin/repo.c b/builtin/repo.c\nindex 0ea045abc1..23c5ee88b0 100644\n--- a/builtin/repo.c\n+++ b/builtin/repo.c\n@@ -17,8 +17,8 @@\n #include \"utf8.h\"\n \n static const char *const repo_usage[] = {\n-\t\"git repo info [--format=(keyvalue|nul) | -z] [--all | <key>...]\",\n-\t\"git repo structure [--format=(table|keyvalue|nul) | -z]\",\n+\t\"git repo info [--format=(lines|nul) | -z] [--all | <key>...]\",\n+\t\"git repo structure [--format=(table|lines|nul) | -z]\",\n \tNULL\n };\n \n@@ -26,7 +26,7 @@ typedef int get_value_fn(struct repository *repo, struct strbuf *buf);\n \n enum output_format {\n \tFORMAT_TABLE,\n-\tFORMAT_KEYVALUE,\n+\tFORMAT_NEWLINE_TERMINATED,\n \tFORMAT_NUL_TERMINATED,\n };\n \n@@ -91,7 +91,7 @@ static void print_field(enum output_format format, const char *key,\n \t\t\tconst char *value)\n {\n \tswitch (format) {\n-\tcase FORMAT_KEYVALUE:\n+\tcase FORMAT_NEWLINE_TERMINATED:\n \t\tprintf(\"%s=\", key);\n \t\tquote_c_style(value, NULL, stdout, 0);\n \t\tputchar('\\n');\n@@ -157,8 +157,8 @@ static int parse_format_cb(const struct option *opt,\n \t\t*format = FORMAT_NUL_TERMINATED;\n \telse if (!strcmp(arg, \"nul\"))\n \t\t*format = FORMAT_NUL_TERMINATED;\n-\telse if (!strcmp(arg, \"keyvalue\"))\n-\t\t*format = FORMAT_KEYVALUE;\n+\telse if (!strcmp(arg, \"lines\"))\n+\t\t*format = FORMAT_NEWLINE_TERMINATED;\n \telse if (!strcmp(arg, \"table\"))\n \t\t*format = FORMAT_TABLE;\n \telse\n@@ -170,7 +170,7 @@ static int parse_format_cb(const struct option *opt,\n static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t\t\t struct repository *repo)\n {\n-\tenum output_format format = FORMAT_KEYVALUE;\n+\tenum output_format format = FORMAT_NEWLINE_TERMINATED;\n \tint all_keys = 0;\n \tstruct option options[] = {\n \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n@@ -185,7 +185,8 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t};\n \n \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n-\tif (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED)\n+\n+\tif (format != FORMAT_NEWLINE_TERMINATED && format != FORMAT_NUL_TERMINATED)\n \t\tdie(_(\"unsupported output format\"));\n \n \tif (all_keys && argc)\n@@ -671,7 +672,7 @@ static int cmd_repo_structure(int argc, const char **argv, const char *prefix,\n \t\tstats_table_setup_structure(&table, &stats);\n \t\tstats_table_print_structure(&table);\n \t\tbreak;\n-\tcase FORMAT_KEYVALUE:\n+\tcase FORMAT_NEWLINE_TERMINATED:\n \t\tstructure_keyvalue_print(&stats, '=', '\\n');\n \t\tbreak;\n \tcase FORMAT_NUL_TERMINATED:\ndiff --git a/t/t1900-repo.sh b/t/t1900-repo.sh\nindex 51d55f11a5..4155211e5d 100755\n--- a/t/t1900-repo.sh\n+++ b/t/t1900-repo.sh\n@@ -34,7 +34,7 @@ test_repo_info () {\n \t\teval \"$init_command $repo_name\"\n \t'\n \n-\ttest_expect_success \"keyvalue: $label\" '\n+\ttest_expect_success \"lines: $label\" '\n \t\techo \"$key=$expected_value\" > expect &&\n \t\tgit -C \"$repo_name\" repo info \"$key\" >actual &&\n \t\ttest_cmp expect actual\n@@ -115,7 +115,7 @@ test_expect_success '-z uses nul-terminated format' '\n \n test_expect_success 'git repo info uses the last requested format' '\n \techo \"layout.bare=false\" >expected &&\n-\tgit repo info --format=nul -z --format=keyvalue layout.bare >actual &&\n+\tgit repo info --format=nul -z --format=lines layout.bare >actual &&\n \ttest_cmp expected actual\n '\n \ndiff --git a/t/t1901-repo-structure.sh b/t/t1901-repo-structure.sh\nindex 17ff164b05..a6f2591d9a 100755\n--- a/t/t1901-repo-structure.sh\n+++ b/t/t1901-repo-structure.sh\n@@ -113,7 +113,7 @@ test_expect_success SHA1 'repository with references and objects' '\n \t)\n '\n \n-test_expect_success SHA1 'keyvalue and nul format' '\n+test_expect_success SHA1 'lines and nul format' '\n \ttest_when_finished \"rm -rf repo\" &&\n \tgit init repo &&\n \t(\n@@ -140,7 +140,7 @@ test_expect_success SHA1 'keyvalue and nul format' '\n \t\tobjects.tags.disk_size=$(object_type_disk_usage tag)\n \t\tEOF\n \n-\t\tgit repo structure --format=keyvalue >out 2>err &&\n+\t\tgit repo structure --format=lines >out 2>err &&\n \n \t\ttest_cmp expect out &&\n \t\ttest_line_count = 0 err &&\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"535996","messageId":"20260214005818.37349-3-lucasseikioshiro@gmail.com","threadId":"64592","inReplyTo":"20260214005818.37349-1-lucasseikioshiro@gmail.com","subject":"[PATCH v6 2/2] repo: add new flag --keys to git-repo-info","fromName":"Lucas Seiki Oshiro","fromEmail":"lucasseikioshiro@gmail.com","sentAt":"2026-02-14T00:35:16Z","receivedAt":"2026-02-14T00:58:36Z","isPatch":true,"sender":{"key":"lucasseikioshiro@gmail.com","avatar":"https://avatars.githubusercontent.com/u/12701580?v=4"},"body":"If the user wants to find what are the available keys, they need to\neither check the documentation or to ask for all the key-value pairs\nby using --all.\n\nAdd a new flag --keys for listing only the available keys without\nlisting the values.\n\nSigned-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>\n---\n Documentation/git-repo.adoc | 11 ++++++++++\n builtin/repo.c              | 32 +++++++++++++++++++++++++++++\n t/t1900-repo.sh             | 40 +++++++++++++++++++++++++++----------\n 3 files changed, 72 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc\nindex 693e1bbced..319d30bd86 100644\n--- a/Documentation/git-repo.adoc\n+++ b/Documentation/git-repo.adoc\n@@ -9,6 +9,7 @@ SYNOPSIS\n --------\n [synopsis]\n git repo info [--format=(lines|nul) | -z] [--all | <key>...]\n+git repo info --keys [--format=(lines|nul) | -z]\n git repo structure [--format=(table|lines|nul) | -z]\n \n DESCRIPTION\n@@ -45,6 +46,16 @@ supported:\n +\n `-z` is an alias for `--format=nul`.\n \n+`info --keys [--format=(lines|nul) | -z]`::\n+\tList all the available keys, one per line. The output format can be chosen\n+\tthrough the flag `--format`. The following formats are supported:\n++\n+`lines`:::\n+\tOutput the keys one per line. This is the default.\n+\n+`nul`:::\n+\tSimilar to `lines`, but using a _NUL_ character after each value.\n+\n `structure [--format=(table|lines|nul) | -z]`::\n \tRetrieve statistics about the current repository structure. The\n \tfollowing kinds of information are reported:\ndiff --git a/builtin/repo.c b/builtin/repo.c\nindex 23c5ee88b0..6a62a6020a 100644\n--- a/builtin/repo.c\n+++ b/builtin/repo.c\n@@ -18,6 +18,7 @@\n \n static const char *const repo_usage[] = {\n \t\"git repo info [--format=(lines|nul) | -z] [--all | <key>...]\",\n+\t\"git repo info --keys [--format=(lines|nul) | -z]\",\n \t\"git repo structure [--format=(table|lines|nul) | -z]\",\n \tNULL\n };\n@@ -148,6 +149,29 @@ static int print_all_fields(struct repository *repo,\n \treturn 0;\n }\n \n+static int print_keys(enum output_format format)\n+{\n+\tchar sep;\n+\n+\tswitch (format) {\n+\tcase FORMAT_NEWLINE_TERMINATED:\n+\t\tsep = '\\n';\n+\t\tbreak;\n+\tcase FORMAT_NUL_TERMINATED:\n+\t\tsep = '\\0';\n+\t\tbreak;\n+\tdefault:\n+\t\tdie(_(\"--keys can only be used with --format=lines or --format=nul\"));\n+\t}\n+\n+\tfor (size_t i = 0; i < ARRAY_SIZE(repo_info_fields); i++) {\n+\t\tconst struct field *field = &repo_info_fields[i];\n+\t\tprintf(\"%s%c\", field->key, sep);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int parse_format_cb(const struct option *opt,\n \t\t\t   const char *arg, int unset UNUSED)\n {\n@@ -172,6 +196,7 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n {\n \tenum output_format format = FORMAT_NEWLINE_TERMINATED;\n \tint all_keys = 0;\n+\tint show_keys = 0;\n \tstruct option options[] = {\n \t\tOPT_CALLBACK_F(0, \"format\", &format, N_(\"format\"),\n \t\t\t       N_(\"output format\"),\n@@ -181,11 +206,18 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,\n \t\t\t       PARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\t       parse_format_cb),\n \t\tOPT_BOOL(0, \"all\", &all_keys, N_(\"print all keys/values\")),\n+\t\tOPT_BOOL(0, \"keys\", &show_keys, N_(\"show keys\")),\n \t\tOPT_END()\n \t};\n \n \targc = parse_options(argc, argv, prefix, options, repo_usage, 0);\n \n+\tif (show_keys && (all_keys || argc))\n+\t\tdie(_(\"--keys cannot be used with a <key> or --all\"));\n+\n+\tif (show_keys)\n+\t\treturn print_keys(format);\n+\n \tif (format != FORMAT_NEWLINE_TERMINATED && format != FORMAT_NUL_TERMINATED)\n \t\tdie(_(\"unsupported output format\"));\n \ndiff --git a/t/t1900-repo.sh b/t/t1900-repo.sh\nindex 4155211e5d..a9eb07abe8 100755\n--- a/t/t1900-repo.sh\n+++ b/t/t1900-repo.sh\n@@ -4,15 +4,6 @@ test_description='test git repo-info'\n \n . ./test-lib.sh\n \n-# git-repo-info keys. It must contain the same keys listed in the const\n-# repo_info_fields, in lexicographical order.\n-REPO_INFO_KEYS='\n-\tlayout.bare\n-\tlayout.shallow\n-\tobject.format\n-\treferences.format\n-'\n-\n # Test whether a key-value pair is correctly returned\n #\n # Usage: test_repo_info <label> <init command> <repo_name> <key> <expected value>\n@@ -119,8 +110,8 @@ test_expect_success 'git repo info uses the last requested format' '\n \ttest_cmp expected actual\n '\n \n-test_expect_success 'git repo info --all returns all key-value pairs' '\n-\tgit repo info $REPO_INFO_KEYS >expect &&\n+test_expect_success 'git repo info --all and git repo info $(git repo info --keys) output the same data' '\n+\tgit repo info $(git repo info --keys) >expect &&\n \tgit repo info --all >actual &&\n \ttest_cmp expect actual\n '\n@@ -131,4 +122,31 @@ test_expect_success 'git repo info --all <key> aborts' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'git repo info --keys --format=nul uses nul-terminated output' '\n+\tgit repo info --keys --format=lines >lines &&\n+\tlf_to_nul <lines >expect &&\n+\tgit repo info --keys --format=nul >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git repo info --keys aborts when using --format other than lines or nul' '\n+\techo \"fatal: --keys can only be used with --format=lines or --format=nul\" >expect &&\n+\ttest_must_fail git repo info --keys --format=table 2>actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git repo info --keys aborts when requesting keys' '\n+\techo \"fatal: --keys cannot be used with a <key> or --all\" >expect &&\n+\ttest_must_fail git repo info --keys --all 2>actual_all &&\n+\ttest_must_fail git repo info --keys some.key 2>actual_key &&\n+\ttest_cmp expect actual_all &&\n+\ttest_cmp expect actual_key\n+'\n+\n+test_expect_success 'git repo info --keys uses lines as its default output format' '\n+\tgit repo info --keys --format=lines >expect &&\n+\tgit repo info --keys >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n2.50.1 (Apple Git-155)\n\n"},{"id":"536028","messageId":"xmqq7bsfgpkv.fsf@gitster.g","threadId":"64592","inReplyTo":"20260214005818.37349-1-lucasseikioshiro@gmail.com","subject":"Re: [PATCH v6 0/2] repo: add --keys and rename \"keyvalue\" to \"lines\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-14T18:14:24Z","receivedAt":"2026-02-14T18:14:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lucas Seiki Oshiro <lucasseikioshiro@gmail.com> writes:\n\n> This v6 addresses these issues raised by Patrick:\n>\n> - It renames `FORMAT_LINES` to `FORMAT_NEWLINE_TERMINATED`\n> - Change the commit messsage of the first patch (I'm using Patrick's\n>   suggestion)\n> - It capitalizes the new paragraphs\n>\n> There was a discussion about the name of the new format (\"lines\" vs\n> \"newline\") [1]. Personally I prefer \"lines\" instead of \"newline\" because\n> I understand the --format flag expects a format name (e.g. `table`,\n> `lines`) instead of the delimiter, being `nul` only a short form of\n> \"nul-terminated\". But, of course, I'm open to other opinions about it\n> :-).\n\nI'll refrain from commenting on this part, as I am not good at\nnaming ;-)\n\nChanges relative to the previous round look all good.  Will replace.\n\nLet's mark it for 'next'.\n\nThanks.\n"},{"id":"536089","messageId":"aZLARuSCuy8wYLUA@pks.im","threadId":"64592","inReplyTo":"xmqq7bsfgpkv.fsf@gitster.g","subject":"Re: [PATCH v6 0/2] repo: add --keys and rename \"keyvalue\" to \"lines\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-16T06:59:18Z","receivedAt":"2026-02-16T06:59:25Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Sat, Feb 14, 2026 at 10:14:24AM -0800, Junio C Hamano wrote:\n> Lucas Seiki Oshiro <lucasseikioshiro@gmail.com> writes:\n> \n> > This v6 addresses these issues raised by Patrick:\n> >\n> > - It renames `FORMAT_LINES` to `FORMAT_NEWLINE_TERMINATED`\n> > - Change the commit messsage of the first patch (I'm using Patrick's\n> >   suggestion)\n> > - It capitalizes the new paragraphs\n> >\n> > There was a discussion about the name of the new format (\"lines\" vs\n> > \"newline\") [1]. Personally I prefer \"lines\" instead of \"newline\" because\n> > I understand the --format flag expects a format name (e.g. `table`,\n> > `lines`) instead of the delimiter, being `nul` only a short form of\n> > \"nul-terminated\". But, of course, I'm open to other opinions about it\n> > :-).\n> \n> I'll refrain from commenting on this part, as I am not good at\n> naming ;-)\n> \n> Changes relative to the previous round look all good.  Will replace.\n> \n> Let's mark it for 'next'.\n\nAgreed, this version looks good to me. Thanks!\n\nPatrick\n"}]}