Merge branch 'lo/repo-info-all'

"git repo info" learned "--all" option.

* lo/repo-info-all:
  repo: add --all to git-repo-info
  repo: factor out field printing to dedicated function
main
Junio C Hamano 2025-11-30 18:31:39 -08:00
commit 0fec747d59
3 changed files with 69 additions and 21 deletions

View File

@ -8,7 +8,7 @@ git-repo - Retrieve information about the repository
SYNOPSIS SYNOPSIS
-------- --------
[synopsis] [synopsis]
git repo info [--format=(keyvalue|nul)] [-z] [<key>...] git repo info [--format=(keyvalue|nul)] [-z] [--all | <key>...]
git repo structure [--format=(table|keyvalue|nul)] git repo structure [--format=(table|keyvalue|nul)]


DESCRIPTION DESCRIPTION
@ -19,13 +19,13 @@ THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.


COMMANDS COMMANDS
-------- --------
`info [--format=(keyvalue|nul)] [-z] [<key>...]`:: `info [--format=(keyvalue|nul)] [-z] [--all | <key>...]`::
Retrieve metadata-related information about the current repository. Only Retrieve metadata-related information about the current repository. Only
the requested data will be returned based on their keys (see "INFO KEYS" the requested data will be returned based on their keys (see "INFO KEYS"
section below). section below).
+ +
The values are returned in the same order in which their respective keys were The values are returned in the same order in which their respective keys were
requested. requested. The `--all` flag requests the values for all the available keys.
+ +
The output format can be chosen through the flag `--format`. Two formats are The output format can be chosen through the flag `--format`. Two formats are
supported: supported:

View File

@ -15,7 +15,7 @@
#include "utf8.h" #include "utf8.h"


static const char *const repo_usage[] = { static const char *const repo_usage[] = {
"git repo info [--format=(keyvalue|nul)] [-z] [<key>...]", "git repo info [--format=(keyvalue|nul)] [-z] [--all | <key>...]",
"git repo structure [--format=(table|keyvalue|nul)]", "git repo structure [--format=(table|keyvalue|nul)]",
NULL NULL
}; };
@ -85,13 +85,29 @@ static get_value_fn *get_value_fn_for_key(const char *key)
return found ? found->get_value : NULL; return found ? found->get_value : NULL;
} }


static void print_field(enum output_format format, const char *key,
const char *value)
{
switch (format) {
case FORMAT_KEYVALUE:
printf("%s=", key);
quote_c_style(value, NULL, stdout, 0);
putchar('\n');
break;
case FORMAT_NUL_TERMINATED:
printf("%s\n%s%c", key, value, '\0');
break;
default:
BUG("not a valid output format: %d", format);
}
}

static int print_fields(int argc, const char **argv, static int print_fields(int argc, const char **argv,
struct repository *repo, struct repository *repo,
enum output_format format) enum output_format format)
{ {
int ret = 0; int ret = 0;
struct strbuf valbuf = STRBUF_INIT; struct strbuf valbuf = STRBUF_INIT;
struct strbuf quotbuf = STRBUF_INIT;


for (int i = 0; i < argc; i++) { for (int i = 0; i < argc; i++) {
get_value_fn *get_value; get_value_fn *get_value;
@ -105,28 +121,31 @@ static int print_fields(int argc, const char **argv,
} }


strbuf_reset(&valbuf); strbuf_reset(&valbuf);
strbuf_reset(&quotbuf);

get_value(repo, &valbuf); get_value(repo, &valbuf);

print_field(format, key, valbuf.buf);
switch (format) {
case FORMAT_KEYVALUE:
quote_c_style(valbuf.buf, &quotbuf, NULL, 0);
printf("%s=%s\n", key, quotbuf.buf);
break;
case FORMAT_NUL_TERMINATED:
printf("%s\n%s%c", key, valbuf.buf, '\0');
break;
default:
BUG("not a valid output format: %d", format);
}
} }


strbuf_release(&valbuf); strbuf_release(&valbuf);
strbuf_release(&quotbuf);
return ret; return ret;
} }


static int print_all_fields(struct repository *repo,
enum output_format format)
{
struct strbuf valbuf = STRBUF_INIT;

for (size_t i = 0; i < ARRAY_SIZE(repo_info_fields); i++) {
const struct field *field = &repo_info_fields[i];

strbuf_reset(&valbuf);
field->get_value(repo, &valbuf);
print_field(format, field->key, valbuf.buf);
}

strbuf_release(&valbuf);
return 0;
}

static int parse_format_cb(const struct option *opt, static int parse_format_cb(const struct option *opt,
const char *arg, int unset UNUSED) const char *arg, int unset UNUSED)
{ {
@ -150,6 +169,7 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,
struct repository *repo) struct repository *repo)
{ {
enum output_format format = FORMAT_KEYVALUE; enum output_format format = FORMAT_KEYVALUE;
int all_keys = 0;
struct option options[] = { struct option options[] = {
OPT_CALLBACK_F(0, "format", &format, N_("format"), OPT_CALLBACK_F(0, "format", &format, N_("format"),
N_("output format"), N_("output format"),
@ -158,6 +178,7 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,
N_("synonym for --format=nul"), N_("synonym for --format=nul"),
PARSE_OPT_NONEG | PARSE_OPT_NOARG, PARSE_OPT_NONEG | PARSE_OPT_NOARG,
parse_format_cb), parse_format_cb),
OPT_BOOL(0, "all", &all_keys, N_("print all keys/values")),
OPT_END() OPT_END()
}; };


@ -165,7 +186,13 @@ static int cmd_repo_info(int argc, const char **argv, const char *prefix,
if (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED) if (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED)
die(_("unsupported output format")); die(_("unsupported output format"));


return print_fields(argc, argv, repo, format); if (all_keys && argc)
die(_("--all and <key> cannot be used together"));

if (all_keys)
return print_all_fields(repo, format);
else
return print_fields(argc, argv, repo, format);
} }


struct ref_stats { struct ref_stats {

View File

@ -4,6 +4,15 @@ test_description='test git repo-info'


. ./test-lib.sh . ./test-lib.sh


# git-repo-info keys. It must contain the same keys listed in the const
# repo_info_fields, in lexicographical order.
REPO_INFO_KEYS='
layout.bare
layout.shallow
object.format
references.format
'

# Test whether a key-value pair is correctly returned # Test whether a key-value pair is correctly returned
# #
# Usage: test_repo_info <label> <init command> <repo_name> <key> <expected value> # Usage: test_repo_info <label> <init command> <repo_name> <key> <expected value>
@ -110,4 +119,16 @@ test_expect_success 'git repo info uses the last requested format' '
test_cmp expected actual test_cmp expected actual
' '


test_expect_success 'git repo info --all returns all key-value pairs' '
git repo info $REPO_INFO_KEYS >expect &&
git repo info --all >actual &&
test_cmp expect actual
'

test_expect_success 'git repo info --all <key> aborts' '
echo "fatal: --all and <key> cannot be used together" >expect &&
test_must_fail git repo info --all object.format 2>actual &&
test_cmp expect actual
'

test_done test_done