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]
git repo info [--format=(keyvalue|nul)] [-z] [<key>...]
git repo info [--format=(keyvalue|nul)] [-z] [--all | <key>...]
git repo structure [--format=(table|keyvalue|nul)]

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

COMMANDS
--------
`info [--format=(keyvalue|nul)] [-z] [<key>...]`::
`info [--format=(keyvalue|nul)] [-z] [--all | <key>...]`::
Retrieve metadata-related information about the current repository. Only
the requested data will be returned based on their keys (see "INFO KEYS"
section below).
+
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
supported:

View File

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

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)]",
NULL
};
@ -85,13 +85,29 @@ static get_value_fn *get_value_fn_for_key(const char *key)
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,
struct repository *repo,
enum output_format format)
{
int ret = 0;
struct strbuf valbuf = STRBUF_INIT;
struct strbuf quotbuf = STRBUF_INIT;

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

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

get_value(repo, &valbuf);

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);
}
print_field(format, key, valbuf.buf);
}

strbuf_release(&valbuf);
strbuf_release(&quotbuf);
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,
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)
{
enum output_format format = FORMAT_KEYVALUE;
int all_keys = 0;
struct option options[] = {
OPT_CALLBACK_F(0, "format", &format, N_("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"),
PARSE_OPT_NONEG | PARSE_OPT_NOARG,
parse_format_cb),
OPT_BOOL(0, "all", &all_keys, N_("print all keys/values")),
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)
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 {

View File

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

. ./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
#
# 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_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