builtin/repo: add inflated object info to keyvalue structure output
The structure subcommand for git-repo(1) outputs basic count information for objects and references. Extend this output to also provide information regarding total size of inflated objects by object type. For now, object size by object type info is only added to the keyvalue and nul output formats. In a subsequent commit, this info is also added to the table format. 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
3e114496e48e665d2bb9e0c0917e6051d60392ea
3 files changed
+39
-1
Documentation/git-repo.adoc
+1
@@ -50,6 +50,7 @@ supported:
50
+
51
* Reference counts categorized by type
52
* Reachable object counts categorized by type
53
+* Total inflated size of reachable objects by type
54
55
+
56
The output format can be chosen through the flag `--format`. Three formats are
builtin/repo.c
+33
@@ -2,6 +2,8 @@
2
3
#include "builtin.h"
4
#include "environment.h"
5
+#include "hex.h"
6
+#include "odb.h"
7
#include "parse-options.h"
8
#include "path-walk.h"
9
#include "progress.h"
@@ -211,6 +213,7 @@ struct object_values {
213
214
struct object_stats {
215
struct object_values type_counts;
216
+ struct object_values inflated_sizes;
217
};
218
219
struct repo_structure {
@@ -423,6 +426,15 @@ static void structure_keyvalue_print(struct repo_structure *stats,
426
printf("objects.tags.count%c%" PRIuMAX "%c", key_delim,
427
(uintmax_t)stats->objects.type_counts.tags, value_delim);
428
429
+ printf("objects.commits.inflated_size%c%" PRIuMAX "%c", key_delim,
430
+ (uintmax_t)stats->objects.inflated_sizes.commits, value_delim);
431
+ printf("objects.trees.inflated_size%c%" PRIuMAX "%c", key_delim,
432
+ (uintmax_t)stats->objects.inflated_sizes.trees, value_delim);
433
+ printf("objects.blobs.inflated_size%c%" PRIuMAX "%c", key_delim,
434
+ (uintmax_t)stats->objects.inflated_sizes.blobs, value_delim);
435
+ printf("objects.tags.inflated_size%c%" PRIuMAX "%c", key_delim,
436
+ (uintmax_t)stats->objects.inflated_sizes.tags, value_delim);
437
+
438
fflush(stdout);
439
}
440
@@ -486,6 +498,7 @@ static void structure_count_references(struct ref_stats *stats,
498
}
499
500
struct count_objects_data {
501
+ struct object_database *odb;
502
struct object_stats *stats;
503
struct progress *progress;
504
};
@@ -495,20 +508,39 @@ static int count_objects(const char *path UNUSED, struct oid_array *oids,
508
{
509
struct count_objects_data *data = cb_data;
510
struct object_stats *stats = data->stats;
511
+ size_t inflated_total = 0;
512
size_t object_count;
513
514
+ for (size_t i = 0; i < oids->nr; i++) {
515
+ struct object_info oi = OBJECT_INFO_INIT;
516
+ unsigned long inflated;
517
+
518
+ oi.sizep = &inflated;
519
+
520
+ if (odb_read_object_info_extended(data->odb, &oids->oid[i], &oi,
521
+ OBJECT_INFO_SKIP_FETCH_OBJECT |
522
+ OBJECT_INFO_QUICK) < 0)
523
+ continue;
524
+
525
+ inflated_total += inflated;
526
+ }
527
+
528
switch (type) {
529
case OBJ_TAG:
530
stats->type_counts.tags += oids->nr;
531
+ stats->inflated_sizes.tags += inflated_total;
532
break;
533
case OBJ_COMMIT:
534
stats->type_counts.commits += oids->nr;
535
+ stats->inflated_sizes.commits += inflated_total;
536
break;
537
case OBJ_TREE:
538
stats->type_counts.trees += oids->nr;
539
+ stats->inflated_sizes.trees += inflated_total;
540
break;
541
case OBJ_BLOB:
542
stats->type_counts.blobs += oids->nr;
543
+ stats->inflated_sizes.blobs += inflated_total;
544
break;
545
default:
546
BUG("invalid object type");
@@ -526,6 +558,7 @@ static void structure_count_objects(struct object_stats *stats,
558
{
559
struct path_walk_info info = PATH_WALK_INFO_INIT;
560
struct count_objects_data data = {
561
+ .odb = repo->objects,
562
.stats = stats,
563
};
564
t/t1901-repo-structure.sh
+5
-1
@@ -73,7 +73,7 @@ test_expect_success 'repository with references and objects' '
73
)
74
'
75
76
-test_expect_success 'keyvalue and nul format' '
76
+test_expect_success SHA1 'keyvalue and nul format' '
77
test_when_finished "rm -rf repo" &&
78
git init repo &&
79
(
@@ -90,6 +90,10 @@ test_expect_success 'keyvalue and nul format' '
90
objects.trees.count=42
91
objects.blobs.count=42
92
objects.tags.count=1
93
+ objects.commits.inflated_size=9225
94
+ objects.trees.inflated_size=28554
95
+ objects.blobs.inflated_size=453
96
+ objects.tags.inflated_size=132
97
EOF
98
99
git repo structure --format=keyvalue >out 2>err &&