aboutsummaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-12-30 12:58:19 +0900
committerJunio C Hamano <gitster@pobox.com>2025-12-30 12:58:19 +0900
commit02e9bc33921bbb070c49aa1aff48ae4317537d83 (patch)
tree7e7209041d113bd49eb3ecb2ef2138015585964f /builtin
parent7c7698a654a7a0031f65b0ab0c1c4e438e95df60 (diff)
parentdf1b071fedfddc322fa2a5e0f71d23cb05949d6f (diff)
downloadgit-02e9bc33921bbb070c49aa1aff48ae4317537d83.tar.xz
Merge branch 'jt/repo-struct-more-objinfo'
More object database related information are shown in "git repo structure" output. * jt/repo-struct-more-objinfo: builtin/repo: add object disk size info to structure table builtin/repo: add disk size info to keyvalue stucture output builtin/repo: add inflated object info to structure table builtin/repo: add inflated object info to keyvalue structure output builtin/repo: humanise count values in structure output strbuf: split out logic to humanise byte values builtin/repo: group per-type object values into struct
Diffstat (limited to 'builtin')
-rw-r--r--builtin/repo.c175
1 files changed, 146 insertions, 29 deletions
diff --git a/builtin/repo.c b/builtin/repo.c
index 0dd41b1778..0ea045abc1 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"
@@ -202,13 +204,19 @@ struct ref_stats {
size_t others;
};
-struct object_stats {
+struct object_values {
size_t tags;
size_t commits;
size_t trees;
size_t blobs;
};
+struct object_stats {
+ struct object_values type_counts;
+ struct object_values inflated_sizes;
+ struct object_values disk_sizes;
+};
+
struct repo_structure {
struct ref_stats refs;
struct object_stats objects;
@@ -219,6 +227,7 @@ struct stats_table {
int name_col_width;
int value_col_width;
+ int unit_col_width;
};
/*
@@ -226,6 +235,7 @@ struct stats_table {
*/
struct stats_table_entry {
char *value;
+ const char *unit;
};
static void stats_table_vaddf(struct stats_table *table,
@@ -246,11 +256,18 @@ static void stats_table_vaddf(struct stats_table *table,
if (name_width > table->name_col_width)
table->name_col_width = name_width;
- if (entry) {
+ if (!entry)
+ return;
+ if (entry->value) {
int value_width = utf8_strwidth(entry->value);
if (value_width > table->value_col_width)
table->value_col_width = value_width;
}
+ if (entry->unit) {
+ int unit_width = utf8_strwidth(entry->unit);
+ if (unit_width > table->unit_col_width)
+ table->unit_col_width = unit_width;
+ }
}
static void stats_table_addf(struct stats_table *table, const char *format, ...)
@@ -269,7 +286,21 @@ static void stats_table_count_addf(struct stats_table *table, size_t value,
va_list ap;
CALLOC_ARRAY(entry, 1);
- entry->value = xstrfmt("%" PRIuMAX, (uintmax_t)value);
+ humanise_count(value, &entry->value, &entry->unit);
+
+ va_start(ap, format);
+ stats_table_vaddf(table, entry, format, ap);
+ va_end(ap);
+}
+
+static void stats_table_size_addf(struct stats_table *table, size_t value,
+ const char *format, ...)
+{
+ struct stats_table_entry *entry;
+ va_list ap;
+
+ CALLOC_ARRAY(entry, 1);
+ humanise_bytes(value, &entry->value, &entry->unit, HUMANISE_COMPACT);
va_start(ap, format);
stats_table_vaddf(table, entry, format, ap);
@@ -281,9 +312,9 @@ static inline size_t get_total_reference_count(struct ref_stats *stats)
return stats->branches + stats->remotes + stats->tags + stats->others;
}
-static inline size_t get_total_object_count(struct object_stats *stats)
+static inline size_t get_total_object_values(struct object_values *values)
{
- return stats->tags + stats->commits + stats->trees + stats->blobs;
+ return values->tags + values->commits + values->trees + values->blobs;
}
static void stats_table_setup_structure(struct stats_table *table,
@@ -291,7 +322,9 @@ static void stats_table_setup_structure(struct stats_table *table,
{
struct object_stats *objects = &stats->objects;
struct ref_stats *refs = &stats->refs;
- size_t object_total;
+ size_t inflated_object_total;
+ size_t object_count_total;
+ size_t disk_object_total;
size_t ref_total;
ref_total = get_total_reference_count(refs);
@@ -302,34 +335,66 @@ static void stats_table_setup_structure(struct stats_table *table,
stats_table_count_addf(table, refs->remotes, " * %s", _("Remotes"));
stats_table_count_addf(table, refs->others, " * %s", _("Others"));
- object_total = get_total_object_count(objects);
+ object_count_total = get_total_object_values(&objects->type_counts);
stats_table_addf(table, "");
stats_table_addf(table, "* %s", _("Reachable objects"));
- stats_table_count_addf(table, object_total, " * %s", _("Count"));
- stats_table_count_addf(table, objects->commits, " * %s", _("Commits"));
- stats_table_count_addf(table, objects->trees, " * %s", _("Trees"));
- stats_table_count_addf(table, objects->blobs, " * %s", _("Blobs"));
- stats_table_count_addf(table, objects->tags, " * %s", _("Tags"));
+ stats_table_count_addf(table, object_count_total, " * %s", _("Count"));
+ stats_table_count_addf(table, objects->type_counts.commits,
+ " * %s", _("Commits"));
+ stats_table_count_addf(table, objects->type_counts.trees,
+ " * %s", _("Trees"));
+ stats_table_count_addf(table, objects->type_counts.blobs,
+ " * %s", _("Blobs"));
+ stats_table_count_addf(table, objects->type_counts.tags,
+ " * %s", _("Tags"));
+
+ inflated_object_total = get_total_object_values(&objects->inflated_sizes);
+ stats_table_size_addf(table, inflated_object_total,
+ " * %s", _("Inflated size"));
+ stats_table_size_addf(table, objects->inflated_sizes.commits,
+ " * %s", _("Commits"));
+ stats_table_size_addf(table, objects->inflated_sizes.trees,
+ " * %s", _("Trees"));
+ stats_table_size_addf(table, objects->inflated_sizes.blobs,
+ " * %s", _("Blobs"));
+ stats_table_size_addf(table, objects->inflated_sizes.tags,
+ " * %s", _("Tags"));
+
+ disk_object_total = get_total_object_values(&objects->disk_sizes);
+ stats_table_size_addf(table, disk_object_total,
+ " * %s", _("Disk size"));
+ stats_table_size_addf(table, objects->disk_sizes.commits,
+ " * %s", _("Commits"));
+ stats_table_size_addf(table, objects->disk_sizes.trees,
+ " * %s", _("Trees"));
+ stats_table_size_addf(table, objects->disk_sizes.blobs,
+ " * %s", _("Blobs"));
+ stats_table_size_addf(table, objects->disk_sizes.tags,
+ " * %s", _("Tags"));
}
static void stats_table_print_structure(const struct stats_table *table)
{
const char *name_col_title = _("Repository structure");
const char *value_col_title = _("Value");
- int name_col_width = utf8_strwidth(name_col_title);
- int value_col_width = utf8_strwidth(value_col_title);
+ int title_name_width = utf8_strwidth(name_col_title);
+ int title_value_width = utf8_strwidth(value_col_title);
+ int name_col_width = table->name_col_width;
+ int value_col_width = table->value_col_width;
+ int unit_col_width = table->unit_col_width;
struct string_list_item *item;
struct strbuf buf = STRBUF_INIT;
- if (table->name_col_width > name_col_width)
- name_col_width = table->name_col_width;
- if (table->value_col_width > value_col_width)
- value_col_width = table->value_col_width;
+ if (title_name_width > name_col_width)
+ name_col_width = title_name_width;
+ if (title_value_width > value_col_width + unit_col_width + 1)
+ value_col_width = title_value_width - unit_col_width;
strbuf_addstr(&buf, "| ");
strbuf_utf8_align(&buf, ALIGN_LEFT, name_col_width, name_col_title);
strbuf_addstr(&buf, " | ");
- strbuf_utf8_align(&buf, ALIGN_LEFT, value_col_width, value_col_title);
+ strbuf_utf8_align(&buf, ALIGN_LEFT,
+ value_col_width + unit_col_width + 1, value_col_title);
strbuf_addstr(&buf, " |");
printf("%s\n", buf.buf);
@@ -337,17 +402,20 @@ static void stats_table_print_structure(const struct stats_table *table)
for (int i = 0; i < name_col_width; i++)
putchar('-');
printf(" | ");
- for (int i = 0; i < value_col_width; i++)
+ for (int i = 0; i < value_col_width + unit_col_width + 1; i++)
putchar('-');
printf(" |\n");
for_each_string_list_item(item, &table->rows) {
struct stats_table_entry *entry = item->util;
const char *value = "";
+ const char *unit = "";
if (entry) {
struct stats_table_entry *entry = item->util;
value = entry->value;
+ if (entry->unit)
+ unit = entry->unit;
}
strbuf_reset(&buf);
@@ -355,6 +423,8 @@ static void stats_table_print_structure(const struct stats_table *table)
strbuf_utf8_align(&buf, ALIGN_LEFT, name_col_width, item->string);
strbuf_addstr(&buf, " | ");
strbuf_utf8_align(&buf, ALIGN_RIGHT, value_col_width, value);
+ strbuf_addch(&buf, ' ');
+ strbuf_utf8_align(&buf, ALIGN_LEFT, unit_col_width, unit);
strbuf_addstr(&buf, " |");
printf("%s\n", buf.buf);
}
@@ -389,13 +459,31 @@ static void structure_keyvalue_print(struct repo_structure *stats,
(uintmax_t)stats->refs.others, value_delim);
printf("objects.commits.count%c%" PRIuMAX "%c", key_delim,
- (uintmax_t)stats->objects.commits, value_delim);
+ (uintmax_t)stats->objects.type_counts.commits, value_delim);
printf("objects.trees.count%c%" PRIuMAX "%c", key_delim,
- (uintmax_t)stats->objects.trees, value_delim);
+ (uintmax_t)stats->objects.type_counts.trees, value_delim);
printf("objects.blobs.count%c%" PRIuMAX "%c", key_delim,
- (uintmax_t)stats->objects.blobs, value_delim);
+ (uintmax_t)stats->objects.type_counts.blobs, value_delim);
printf("objects.tags.count%c%" PRIuMAX "%c", key_delim,
- (uintmax_t)stats->objects.tags, value_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);
+
+ 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);
}
@@ -460,6 +548,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;
};
@@ -469,26 +558,53 @@ 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 |
+ OBJECT_INFO_QUICK) < 0)
+ continue;
+
+ inflated_total += inflated;
+ disk_total += disk;
+ }
+
switch (type) {
case OBJ_TAG:
- stats->tags += oids->nr;
+ stats->type_counts.tags += oids->nr;
+ stats->inflated_sizes.tags += inflated_total;
+ stats->disk_sizes.tags += disk_total;
break;
case OBJ_COMMIT:
- stats->commits += oids->nr;
+ stats->type_counts.commits += oids->nr;
+ stats->inflated_sizes.commits += inflated_total;
+ stats->disk_sizes.commits += disk_total;
break;
case OBJ_TREE:
- stats->trees += oids->nr;
+ stats->type_counts.trees += oids->nr;
+ stats->inflated_sizes.trees += inflated_total;
+ stats->disk_sizes.trees += disk_total;
break;
case OBJ_BLOB:
- stats->blobs += oids->nr;
+ stats->type_counts.blobs += oids->nr;
+ stats->inflated_sizes.blobs += inflated_total;
+ stats->disk_sizes.blobs += disk_total;
break;
default:
BUG("invalid object type");
}
- object_count = get_total_object_count(stats);
+ object_count = get_total_object_values(&stats->type_counts);
display_progress(data->progress, object_count);
return 0;
@@ -500,6 +616,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,
};