builtin/repo: add disk size info to keyvalue stucture output
Similar to a prior commit, extend the keyvalue and nul output formats of the git-repo(1) structure command to additionally provide info regarding total object disk sizes by object type. 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
67cecc693f511321b9d96eead24fd42e6a5c0cdc
3 files changed
+29
-1
Documentation/git-repo.adoc
+1
@@ -51,6 +51,7 @@ supported:
51
* Reference counts categorized by type
52
* Reachable object counts categorized by type
53
* Total inflated size of reachable objects by type
54
+* Total disk size of reachable objects by type
55
56
+
57
The output format can be chosen through the flag `--format`. Three formats are
builtin/repo.c
+18
@@ -214,6 +214,7 @@ struct object_values {
214
struct object_stats {
215
struct object_values type_counts;
216
struct object_values inflated_sizes;
217
+ struct object_values disk_sizes;
218
};
219
220
struct repo_structure {
@@ -462,6 +463,15 @@ static void structure_keyvalue_print(struct repo_structure *stats,
463
printf("objects.tags.inflated_size%c%" PRIuMAX "%c", key_delim,
464
(uintmax_t)stats->objects.inflated_sizes.tags, value_delim);
465
466
+ printf("objects.commits.disk_size%c%" PRIuMAX "%c", key_delim,
467
+ (uintmax_t)stats->objects.disk_sizes.commits, value_delim);
468
+ printf("objects.trees.disk_size%c%" PRIuMAX "%c", key_delim,
469
+ (uintmax_t)stats->objects.disk_sizes.trees, value_delim);
470
+ printf("objects.blobs.disk_size%c%" PRIuMAX "%c", key_delim,
471
+ (uintmax_t)stats->objects.disk_sizes.blobs, value_delim);
472
+ printf("objects.tags.disk_size%c%" PRIuMAX "%c", key_delim,
473
+ (uintmax_t)stats->objects.disk_sizes.tags, value_delim);
474
+
475
fflush(stdout);
476
}
477
@@ -536,13 +546,16 @@ static int count_objects(const char *path UNUSED, struct oid_array *oids,
546
struct count_objects_data *data = cb_data;
547
struct object_stats *stats = data->stats;
548
size_t inflated_total = 0;
549
+ size_t disk_total = 0;
550
size_t object_count;
551
552
for (size_t i = 0; i < oids->nr; i++) {
553
struct object_info oi = OBJECT_INFO_INIT;
554
unsigned long inflated;
555
+ off_t disk;
556
557
oi.sizep = &inflated;
558
+ oi.disk_sizep = &disk;
559
560
if (odb_read_object_info_extended(data->odb, &oids->oid[i], &oi,
561
OBJECT_INFO_SKIP_FETCH_OBJECT |
@@ -550,24 +563,29 @@ static int count_objects(const char *path UNUSED, struct oid_array *oids,
563
continue;
564
565
inflated_total += inflated;
566
+ disk_total += disk;
567
}
568
569
switch (type) {
570
case OBJ_TAG:
571
stats->type_counts.tags += oids->nr;
572
stats->inflated_sizes.tags += inflated_total;
573
+ stats->disk_sizes.tags += disk_total;
574
break;
575
case OBJ_COMMIT:
576
stats->type_counts.commits += oids->nr;
577
stats->inflated_sizes.commits += inflated_total;
578
+ stats->disk_sizes.commits += disk_total;
579
break;
580
case OBJ_TREE:
581
stats->type_counts.trees += oids->nr;
582
stats->inflated_sizes.trees += inflated_total;
583
+ stats->disk_sizes.trees += disk_total;
584
break;
585
case OBJ_BLOB:
586
stats->type_counts.blobs += oids->nr;
587
stats->inflated_sizes.blobs += inflated_total;
588
+ stats->disk_sizes.blobs += disk_total;
589
break;
590
default:
591
BUG("invalid object type");
t/t1901-repo-structure.sh
+10
-1
@@ -4,6 +4,11 @@ test_description='test git repo structure'
4
5
. ./test-lib.sh
6
7
+object_type_disk_usage() {
8
+ git rev-list --all --objects --disk-usage --filter=object:type=$1 \
9
+ --filter-provided-objects
10
+}
11
+
12
test_expect_success 'empty repository' '
13
test_when_finished "rm -rf repo" &&
14
git init repo &&
@@ -91,7 +96,7 @@ test_expect_success SHA1 'keyvalue and nul format' '
96
test_commit_bulk 42 &&
97
git tag -a foo -m bar &&
98
94
- cat >expect <<-\EOF &&
99
+ cat >expect <<-EOF &&
100
references.branches.count=1
101
references.tags.count=1
102
references.remotes.count=0
@@ -104,6 +109,10 @@ test_expect_success SHA1 'keyvalue and nul format' '
109
objects.trees.inflated_size=28554
110
objects.blobs.inflated_size=453
111
objects.tags.inflated_size=132
112
+ objects.commits.disk_size=$(object_type_disk_usage commit)
113
+ objects.trees.disk_size=$(object_type_disk_usage tree)
114
+ objects.blobs.disk_size=$(object_type_disk_usage blob)
115
+ objects.tags.disk_size=$(object_type_disk_usage tag)
116
EOF
117
118
git repo structure --format=keyvalue >out 2>err &&