]> git.ipfire.org Git - thirdparty/git.git/commitdiff
builtin/repo: add disk size info to keyvalue stucture output
authorJustin Tobler <jltobler@gmail.com>
Wed, 17 Dec 2025 17:54:03 +0000 (11:54 -0600)
committerJunio C Hamano <gitster@pobox.com>
Thu, 18 Dec 2025 00:02:32 +0000 (09:02 +0900)
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>
Documentation/git-repo.adoc
builtin/repo.c
t/t1901-repo-structure.sh

index 287eee4b93de5a9b52e53edec14ec558b866df18..861073f641e0a3f11d1ae3c1a2f1fa1838c9f906 100644 (file)
@@ -51,6 +51,7 @@ supported:
 * Reference counts categorized by type
 * Reachable object counts categorized by type
 * Total inflated size of reachable objects by type
+* Total disk size of reachable objects by type
 
 +
 The output format can be chosen through the flag `--format`. Three formats are
index 67d7548b8864d390fec6f3dd24b61c8949f3a49e..7ea051f3aff643d24196d3fbe124cf1d6b25936b 100644 (file)
@@ -214,6 +214,7 @@ struct object_values {
 struct object_stats {
        struct object_values type_counts;
        struct object_values inflated_sizes;
+       struct object_values disk_sizes;
 };
 
 struct repo_structure {
@@ -462,6 +463,15 @@ static void structure_keyvalue_print(struct repo_structure *stats,
        printf("objects.tags.inflated_size%c%" PRIuMAX "%c", key_delim,
               (uintmax_t)stats->objects.inflated_sizes.tags, value_delim);
 
+       printf("objects.commits.disk_size%c%" PRIuMAX "%c", key_delim,
+              (uintmax_t)stats->objects.disk_sizes.commits, value_delim);
+       printf("objects.trees.disk_size%c%" PRIuMAX "%c", key_delim,
+              (uintmax_t)stats->objects.disk_sizes.trees, value_delim);
+       printf("objects.blobs.disk_size%c%" PRIuMAX "%c", key_delim,
+              (uintmax_t)stats->objects.disk_sizes.blobs, value_delim);
+       printf("objects.tags.disk_size%c%" PRIuMAX "%c", key_delim,
+              (uintmax_t)stats->objects.disk_sizes.tags, value_delim);
+
        fflush(stdout);
 }
 
@@ -536,13 +546,16 @@ static int count_objects(const char *path UNUSED, struct oid_array *oids,
        struct count_objects_data *data = cb_data;
        struct object_stats *stats = data->stats;
        size_t inflated_total = 0;
+       size_t disk_total = 0;
        size_t object_count;
 
        for (size_t i = 0; i < oids->nr; i++) {
                struct object_info oi = OBJECT_INFO_INIT;
                unsigned long inflated;
+               off_t disk;
 
                oi.sizep = &inflated;
+               oi.disk_sizep = &disk;
 
                if (odb_read_object_info_extended(data->odb, &oids->oid[i], &oi,
                                                  OBJECT_INFO_SKIP_FETCH_OBJECT |
@@ -550,24 +563,29 @@ static int count_objects(const char *path UNUSED, struct oid_array *oids,
                        continue;
 
                inflated_total += inflated;
+               disk_total += disk;
        }
 
        switch (type) {
        case OBJ_TAG:
                stats->type_counts.tags += oids->nr;
                stats->inflated_sizes.tags += inflated_total;
+               stats->disk_sizes.tags += disk_total;
                break;
        case OBJ_COMMIT:
                stats->type_counts.commits += oids->nr;
                stats->inflated_sizes.commits += inflated_total;
+               stats->disk_sizes.commits += disk_total;
                break;
        case OBJ_TREE:
                stats->type_counts.trees += oids->nr;
                stats->inflated_sizes.trees += inflated_total;
+               stats->disk_sizes.trees += disk_total;
                break;
        case OBJ_BLOB:
                stats->type_counts.blobs += oids->nr;
                stats->inflated_sizes.blobs += inflated_total;
+               stats->disk_sizes.blobs += disk_total;
                break;
        default:
                BUG("invalid object type");
index b18213c660ea26e228e7e9537cd510ecb26897f6..dd17caad05da67a62121d21920649831af934502 100755 (executable)
@@ -4,6 +4,11 @@ test_description='test git repo structure'
 
 . ./test-lib.sh
 
+object_type_disk_usage() {
+       git rev-list --all --objects --disk-usage --filter=object:type=$1 \
+               --filter-provided-objects
+}
+
 test_expect_success 'empty repository' '
        test_when_finished "rm -rf repo" &&
        git init repo &&
@@ -91,7 +96,7 @@ test_expect_success SHA1 'keyvalue and nul format' '
                test_commit_bulk 42 &&
                git tag -a foo -m bar &&
 
-               cat >expect <<-\EOF &&
+               cat >expect <<-EOF &&
                references.branches.count=1
                references.tags.count=1
                references.remotes.count=0
@@ -104,6 +109,10 @@ test_expect_success SHA1 'keyvalue and nul format' '
                objects.trees.inflated_size=28554
                objects.blobs.inflated_size=453
                objects.tags.inflated_size=132
+               objects.commits.disk_size=$(object_type_disk_usage commit)
+               objects.trees.disk_size=$(object_type_disk_usage tree)
+               objects.blobs.disk_size=$(object_type_disk_usage blob)
+               objects.tags.disk_size=$(object_type_disk_usage tag)
                EOF
 
                git repo structure --format=keyvalue >out 2>err &&