diff options
| author | Junio C Hamano <gitster@pobox.com> | 2025-12-30 12:58:19 +0900 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2025-12-30 12:58:19 +0900 |
| commit | 02e9bc33921bbb070c49aa1aff48ae4317537d83 (patch) | |
| tree | 7e7209041d113bd49eb3ecb2ef2138015585964f /builtin | |
| parent | 7c7698a654a7a0031f65b0ab0c1c4e438e95df60 (diff) | |
| parent | df1b071fedfddc322fa2a5e0f71d23cb05949d6f (diff) | |
| download | git-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.c | 175 |
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, }; |
