builtin/repo: add inflated object info to structure table

Update the table output format for the git-repo(1) structure command to
begin printing the total inflated object size info by object type. To be
more human-friendly, larger values are scaled down and displayed with
the appropriate unit prefix. Output for the keyvalue and nul formats
remains unchanged.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Justin Tobler
2025-12-17 11:54:02 -06:00
committed by Junio C Hamano
parent 3e114496e4
commit 4d279ae36b
4 changed files with 80 additions and 34 deletions

View File

@@ -292,6 +292,20 @@ static void stats_table_count_addf(struct stats_table *table, size_t value,
va_end(ap); va_end(ap);
} }
static void stats_table_size_addf(struct stats_table *table, size_t value,
const char *format, ...)
{
struct stats_table_entry *entry;
va_list ap;
CALLOC_ARRAY(entry, 1);
humanise_bytes(value, &entry->value, &entry->unit, HUMANISE_COMPACT);
va_start(ap, format);
stats_table_vaddf(table, entry, format, ap);
va_end(ap);
}
static inline size_t get_total_reference_count(struct ref_stats *stats) static inline size_t get_total_reference_count(struct ref_stats *stats)
{ {
return stats->branches + stats->remotes + stats->tags + stats->others; return stats->branches + stats->remotes + stats->tags + stats->others;
@@ -307,7 +321,8 @@ static void stats_table_setup_structure(struct stats_table *table,
{ {
struct object_stats *objects = &stats->objects; struct object_stats *objects = &stats->objects;
struct ref_stats *refs = &stats->refs; struct ref_stats *refs = &stats->refs;
size_t object_total; size_t inflated_object_total;
size_t object_count_total;
size_t ref_total; size_t ref_total;
ref_total = get_total_reference_count(refs); ref_total = get_total_reference_count(refs);
@@ -318,10 +333,10 @@ static void stats_table_setup_structure(struct stats_table *table,
stats_table_count_addf(table, refs->remotes, " * %s", _("Remotes")); stats_table_count_addf(table, refs->remotes, " * %s", _("Remotes"));
stats_table_count_addf(table, refs->others, " * %s", _("Others")); stats_table_count_addf(table, refs->others, " * %s", _("Others"));
object_total = get_total_object_values(&objects->type_counts); object_count_total = get_total_object_values(&objects->type_counts);
stats_table_addf(table, ""); stats_table_addf(table, "");
stats_table_addf(table, "* %s", _("Reachable objects")); stats_table_addf(table, "* %s", _("Reachable objects"));
stats_table_count_addf(table, object_total, " * %s", _("Count")); stats_table_count_addf(table, object_count_total, " * %s", _("Count"));
stats_table_count_addf(table, objects->type_counts.commits, stats_table_count_addf(table, objects->type_counts.commits,
" * %s", _("Commits")); " * %s", _("Commits"));
stats_table_count_addf(table, objects->type_counts.trees, stats_table_count_addf(table, objects->type_counts.trees,
@@ -330,6 +345,18 @@ static void stats_table_setup_structure(struct stats_table *table,
" * %s", _("Blobs")); " * %s", _("Blobs"));
stats_table_count_addf(table, objects->type_counts.tags, stats_table_count_addf(table, objects->type_counts.tags,
" * %s", _("Tags")); " * %s", _("Tags"));
inflated_object_total = get_total_object_values(&objects->inflated_sizes);
stats_table_size_addf(table, inflated_object_total,
" * %s", _("Inflated size"));
stats_table_size_addf(table, objects->inflated_sizes.commits,
" * %s", _("Commits"));
stats_table_size_addf(table, objects->inflated_sizes.trees,
" * %s", _("Trees"));
stats_table_size_addf(table, objects->inflated_sizes.blobs,
" * %s", _("Blobs"));
stats_table_size_addf(table, objects->inflated_sizes.tags,
" * %s", _("Tags"));
} }
static void stats_table_print_structure(const struct stats_table *table) static void stats_table_print_structure(const struct stats_table *table)

View File

@@ -886,11 +886,15 @@ void humanise_bytes(off_t bytes, char **value, const char **unit,
*unit = humanise_rate ? _("KiB/s") : _("KiB"); *unit = humanise_rate ? _("KiB/s") : _("KiB");
} else { } else {
*value = xstrfmt("%u", (unsigned)bytes); *value = xstrfmt("%u", (unsigned)bytes);
*unit = humanise_rate ? if (flags & HUMANISE_COMPACT)
/* TRANSLATORS: IEC 80000-13:2008 byte/second */ /* TRANSLATORS: IEC 80000-13:2008 byte/second and byte */
Q_("byte/s", "bytes/s", bytes) : *unit = humanise_rate ? _("B/s") : _("B");
/* TRANSLATORS: IEC 80000-13:2008 byte */ else
Q_("byte", "bytes", bytes); *unit = humanise_rate ?
/* TRANSLATORS: IEC 80000-13:2008 byte/second */
Q_("byte/s", "bytes/s", bytes) :
/* TRANSLATORS: IEC 80000-13:2008 byte */
Q_("byte", "bytes", bytes);
} }
} }

View File

@@ -372,6 +372,11 @@ enum humanise_flags {
* Use rate based units for humanised values. * Use rate based units for humanised values.
*/ */
HUMANISE_RATE = (1 << 0), HUMANISE_RATE = (1 << 0),
/*
* Use compact "B" unit symbol instead of "byte/bytes" for humanised
* values.
*/
HUMANISE_COMPACT = (1 << 1),
}; };
/** /**

View File

@@ -13,18 +13,23 @@ test_expect_success 'empty repository' '
| Repository structure | Value | | Repository structure | Value |
| -------------------- | ------ | | -------------------- | ------ |
| * References | | | * References | |
| * Count | 0 | | * Count | 0 |
| * Branches | 0 | | * Branches | 0 |
| * Tags | 0 | | * Tags | 0 |
| * Remotes | 0 | | * Remotes | 0 |
| * Others | 0 | | * Others | 0 |
| | | | | |
| * Reachable objects | | | * Reachable objects | |
| * Count | 0 | | * Count | 0 |
| * Commits | 0 | | * Commits | 0 |
| * Trees | 0 | | * Trees | 0 |
| * Blobs | 0 | | * Blobs | 0 |
| * Tags | 0 | | * Tags | 0 |
| * Inflated size | 0 B |
| * Commits | 0 B |
| * Trees | 0 B |
| * Blobs | 0 B |
| * Tags | 0 B |
EOF EOF
git repo structure >out 2>err && git repo structure >out 2>err &&
@@ -34,7 +39,7 @@ test_expect_success 'empty repository' '
) )
' '
test_expect_success 'repository with references and objects' ' test_expect_success SHA1 'repository with references and objects' '
test_when_finished "rm -rf repo" && test_when_finished "rm -rf repo" &&
git init repo && git init repo &&
( (
@@ -49,21 +54,26 @@ test_expect_success 'repository with references and objects' '
git notes add -m foo && git notes add -m foo &&
cat >expect <<-\EOF && cat >expect <<-\EOF &&
| Repository structure | Value | | Repository structure | Value |
| -------------------- | ------ | | -------------------- | ---------- |
| * References | | | * References | |
| * Count | 4 | | * Count | 4 |
| * Branches | 1 | | * Branches | 1 |
| * Tags | 1 | | * Tags | 1 |
| * Remotes | 1 | | * Remotes | 1 |
| * Others | 1 | | * Others | 1 |
| | | | | |
| * Reachable objects | | | * Reachable objects | |
| * Count | 3.02 k | | * Count | 3.02 k |
| * Commits | 1.01 k | | * Commits | 1.01 k |
| * Trees | 1.01 k | | * Trees | 1.01 k |
| * Blobs | 1.01 k | | * Blobs | 1.01 k |
| * Tags | 1 | | * Tags | 1 |
| * Inflated size | 16.03 MiB |
| * Commits | 217.92 KiB |
| * Trees | 15.81 MiB |
| * Blobs | 11.68 KiB |
| * Tags | 132 B |
EOF EOF
git repo structure >out 2>err && git repo structure >out 2>err &&