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>

Justin Tobler committed Dec 17, 2025 at 11:54 UTC 4d279ae36b1d0f68c8a7ba9b986ff9690ddc1af9
4 files changed +80 -34
builtin/repo.c
+30 -3
@@ -292,6 +292,20 @@ static void stats_table_count_addf(struct stats_table *table, size_t value,
292 va_end(ap);
293 }
294
295 +static void stats_table_size_addf(struct stats_table *table, size_t value,
296 + const char *format, ...)
297 +{
298 + struct stats_table_entry *entry;
299 + va_list ap;
300 +
301 + CALLOC_ARRAY(entry, 1);
302 + humanise_bytes(value, &entry->value, &entry->unit, HUMANISE_COMPACT);
303 +
304 + va_start(ap, format);
305 + stats_table_vaddf(table, entry, format, ap);
306 + va_end(ap);
307 +}
308 +
309 static inline size_t get_total_reference_count(struct ref_stats *stats)
310 {
311 return stats->branches + stats->remotes + stats->tags + stats->others;
@@ -307,7 +321,8 @@ static void stats_table_setup_structure(struct stats_table *table,
321 {
322 struct object_stats *objects = &stats->objects;
323 struct ref_stats *refs = &stats->refs;
310 - size_t object_total;
324 + size_t inflated_object_total;
325 + size_t object_count_total;
326 size_t ref_total;
327
328 ref_total = get_total_reference_count(refs);
@@ -318,10 +333,10 @@ static void stats_table_setup_structure(struct stats_table *table,
333 stats_table_count_addf(table, refs->remotes, " * %s", _("Remotes"));
334 stats_table_count_addf(table, refs->others, " * %s", _("Others"));
335
321 - object_total = get_total_object_values(&objects->type_counts);
336 + object_count_total = get_total_object_values(&objects->type_counts);
337 stats_table_addf(table, "");
338 stats_table_addf(table, "* %s", _("Reachable objects"));
324 - stats_table_count_addf(table, object_total, " * %s", _("Count"));
339 + stats_table_count_addf(table, object_count_total, " * %s", _("Count"));
340 stats_table_count_addf(table, objects->type_counts.commits,
341 " * %s", _("Commits"));
342 stats_table_count_addf(table, objects->type_counts.trees,
@@ -330,6 +345,18 @@ static void stats_table_setup_structure(struct stats_table *table,
345 " * %s", _("Blobs"));
346 stats_table_count_addf(table, objects->type_counts.tags,
347 " * %s", _("Tags"));
348 +
349 + inflated_object_total = get_total_object_values(&objects->inflated_sizes);
350 + stats_table_size_addf(table, inflated_object_total,
351 + " * %s", _("Inflated size"));
352 + stats_table_size_addf(table, objects->inflated_sizes.commits,
353 + " * %s", _("Commits"));
354 + stats_table_size_addf(table, objects->inflated_sizes.trees,
355 + " * %s", _("Trees"));
356 + stats_table_size_addf(table, objects->inflated_sizes.blobs,
357 + " * %s", _("Blobs"));
358 + stats_table_size_addf(table, objects->inflated_sizes.tags,
359 + " * %s", _("Tags"));
360 }
361
362 static void stats_table_print_structure(const struct stats_table *table)
strbuf.c
+9 -5
@@ -886,11 +886,15 @@ void humanise_bytes(off_t bytes, char **value, const char **unit,
886 *unit = humanise_rate ? _("KiB/s") : _("KiB");
887 } else {
888 *value = xstrfmt("%u", (unsigned)bytes);
889 - *unit = humanise_rate ?
890 - /* TRANSLATORS: IEC 80000-13:2008 byte/second */
891 - Q_("byte/s", "bytes/s", bytes) :
892 - /* TRANSLATORS: IEC 80000-13:2008 byte */
893 - Q_("byte", "bytes", bytes);
889 + if (flags & HUMANISE_COMPACT)
890 + /* TRANSLATORS: IEC 80000-13:2008 byte/second and byte */
891 + *unit = humanise_rate ? _("B/s") : _("B");
892 + else
893 + *unit = humanise_rate ?
894 + /* TRANSLATORS: IEC 80000-13:2008 byte/second */
895 + Q_("byte/s", "bytes/s", bytes) :
896 + /* TRANSLATORS: IEC 80000-13:2008 byte */
897 + Q_("byte", "bytes", bytes);
898 }
899 }
900
strbuf.h
+5
@@ -372,6 +372,11 @@ enum humanise_flags {
372 * Use rate based units for humanised values.
373 */
374 HUMANISE_RATE = (1 << 0),
375 + /*
376 + * Use compact "B" unit symbol instead of "byte/bytes" for humanised
377 + * values.
378 + */
379 + HUMANISE_COMPACT = (1 << 1),
380 };
381
382 /**
t/t1901-repo-structure.sh
+36 -26
@@ -13,18 +13,23 @@ test_expect_success 'empty repository' '
13 | Repository structure | Value |
14 | -------------------- | ------ |
15 | * References | |
16 - | * Count | 0 |
17 - | * Branches | 0 |
18 - | * Tags | 0 |
19 - | * Remotes | 0 |
20 - | * Others | 0 |
16 + | * Count | 0 |
17 + | * Branches | 0 |
18 + | * Tags | 0 |
19 + | * Remotes | 0 |
20 + | * Others | 0 |
21 | | |
22 | * Reachable objects | |
23 - | * Count | 0 |
24 - | * Commits | 0 |
25 - | * Trees | 0 |
26 - | * Blobs | 0 |
27 - | * Tags | 0 |
23 + | * Count | 0 |
24 + | * Commits | 0 |
25 + | * Trees | 0 |
26 + | * Blobs | 0 |
27 + | * Tags | 0 |
28 + | * Inflated size | 0 B |
29 + | * Commits | 0 B |
30 + | * Trees | 0 B |
31 + | * Blobs | 0 B |
32 + | * Tags | 0 B |
33 EOF
34
35 git repo structure >out 2>err &&
@@ -34,7 +39,7 @@ test_expect_success 'empty repository' '
39 )
40 '
41
37 -test_expect_success 'repository with references and objects' '
42 +test_expect_success SHA1 'repository with references and objects' '
43 test_when_finished "rm -rf repo" &&
44 git init repo &&
45 (
@@ -49,21 +54,26 @@ test_expect_success 'repository with references and objects' '
54 git notes add -m foo &&
55
56 cat >expect <<-\EOF &&
52 - | Repository structure | Value |
53 - | -------------------- | ------ |
54 - | * References | |
55 - | * Count | 4 |
56 - | * Branches | 1 |
57 - | * Tags | 1 |
58 - | * Remotes | 1 |
59 - | * Others | 1 |
60 - | | |
61 - | * Reachable objects | |
62 - | * Count | 3.02 k |
63 - | * Commits | 1.01 k |
64 - | * Trees | 1.01 k |
65 - | * Blobs | 1.01 k |
66 - | * Tags | 1 |
57 + | Repository structure | Value |
58 + | -------------------- | ---------- |
59 + | * References | |
60 + | * Count | 4 |
61 + | * Branches | 1 |
62 + | * Tags | 1 |
63 + | * Remotes | 1 |
64 + | * Others | 1 |
65 + | | |
66 + | * Reachable objects | |
67 + | * Count | 3.02 k |
68 + | * Commits | 1.01 k |
69 + | * Trees | 1.01 k |
70 + | * Blobs | 1.01 k |
71 + | * Tags | 1 |
72 + | * Inflated size | 16.03 MiB |
73 + | * Commits | 217.92 KiB |
74 + | * Trees | 15.81 MiB |
75 + | * Blobs | 11.68 KiB |
76 + | * Tags | 132 B |
77 EOF
78
79 git repo structure >out 2>err &&