aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-repo.adoc1
-rw-r--r--builtin/repo.c33
-rwxr-xr-xt/t1901-repo-structure.sh6
3 files changed, 39 insertions, 1 deletions
diff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc
index 70f0a6d2e4..287eee4b93 100644
--- a/Documentation/git-repo.adoc
+++ b/Documentation/git-repo.adoc
@@ -50,6 +50,7 @@ supported:
+
* Reference counts categorized by type
* Reachable object counts categorized by type
+* Total inflated size of reachable objects by type
+
The output format can be chosen through the flag `--format`. Three formats are
diff --git a/builtin/repo.c b/builtin/repo.c
index 9c61bc3e17..8da321a386 100644
--- a/builtin/repo.c
+++ b/builtin/repo.c
@@ -2,6 +2,8 @@
#include "builtin.h"
#include "environment.h"
+#include "hex.h"
+#include "odb.h"
#include "parse-options.h"
#include "path-walk.h"
#include "progress.h"
@@ -211,6 +213,7 @@ struct object_values {
struct object_stats {
struct object_values type_counts;
+ struct object_values inflated_sizes;
};
struct repo_structure {
@@ -423,6 +426,15 @@ static void structure_keyvalue_print(struct repo_structure *stats,
printf("objects.tags.count%c%" PRIuMAX "%c", key_delim,
(uintmax_t)stats->objects.type_counts.tags, value_delim);
+ printf("objects.commits.inflated_size%c%" PRIuMAX "%c", key_delim,
+ (uintmax_t)stats->objects.inflated_sizes.commits, value_delim);
+ printf("objects.trees.inflated_size%c%" PRIuMAX "%c", key_delim,
+ (uintmax_t)stats->objects.inflated_sizes.trees, value_delim);
+ printf("objects.blobs.inflated_size%c%" PRIuMAX "%c", key_delim,
+ (uintmax_t)stats->objects.inflated_sizes.blobs, value_delim);
+ printf("objects.tags.inflated_size%c%" PRIuMAX "%c", key_delim,
+ (uintmax_t)stats->objects.inflated_sizes.tags, value_delim);
+
fflush(stdout);
}
@@ -486,6 +498,7 @@ static void structure_count_references(struct ref_stats *stats,
}
struct count_objects_data {
+ struct object_database *odb;
struct object_stats *stats;
struct progress *progress;
};
@@ -495,20 +508,39 @@ 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 object_count;
+ for (size_t i = 0; i < oids->nr; i++) {
+ struct object_info oi = OBJECT_INFO_INIT;
+ unsigned long inflated;
+
+ oi.sizep = &inflated;
+
+ if (odb_read_object_info_extended(data->odb, &oids->oid[i], &oi,
+ OBJECT_INFO_SKIP_FETCH_OBJECT |
+ OBJECT_INFO_QUICK) < 0)
+ continue;
+
+ inflated_total += inflated;
+ }
+
switch (type) {
case OBJ_TAG:
stats->type_counts.tags += oids->nr;
+ stats->inflated_sizes.tags += inflated_total;
break;
case OBJ_COMMIT:
stats->type_counts.commits += oids->nr;
+ stats->inflated_sizes.commits += inflated_total;
break;
case OBJ_TREE:
stats->type_counts.trees += oids->nr;
+ stats->inflated_sizes.trees += inflated_total;
break;
case OBJ_BLOB:
stats->type_counts.blobs += oids->nr;
+ stats->inflated_sizes.blobs += inflated_total;
break;
default:
BUG("invalid object type");
@@ -526,6 +558,7 @@ static void structure_count_objects(struct object_stats *stats,
{
struct path_walk_info info = PATH_WALK_INFO_INIT;
struct count_objects_data data = {
+ .odb = repo->objects,
.stats = stats,
};
diff --git a/t/t1901-repo-structure.sh b/t/t1901-repo-structure.sh
index 55fd13ad1b..33237822fd 100755
--- a/t/t1901-repo-structure.sh
+++ b/t/t1901-repo-structure.sh
@@ -73,7 +73,7 @@ test_expect_success 'repository with references and objects' '
)
'
-test_expect_success 'keyvalue and nul format' '
+test_expect_success SHA1 'keyvalue and nul format' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
@@ -90,6 +90,10 @@ test_expect_success 'keyvalue and nul format' '
objects.trees.count=42
objects.blobs.count=42
objects.tags.count=1
+ objects.commits.inflated_size=9225
+ objects.trees.inflated_size=28554
+ objects.blobs.inflated_size=453
+ objects.tags.inflated_size=132
EOF
git repo structure --format=keyvalue >out 2>err &&