mirror of
https://github.com/git/git.git
synced 2026-01-08 01:11:04 +00:00
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
This commit is contained in:
@@ -50,6 +50,8 @@ supported:
|
|||||||
+
|
+
|
||||||
* Reference counts categorized by type
|
* Reference counts categorized by type
|
||||||
* Reachable object 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
|
The output format can be chosen through the flag `--format`. Three formats are
|
||||||
supported:
|
supported:
|
||||||
|
|||||||
175
builtin/repo.c
175
builtin/repo.c
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
|
#include "hex.h"
|
||||||
|
#include "odb.h"
|
||||||
#include "parse-options.h"
|
#include "parse-options.h"
|
||||||
#include "path-walk.h"
|
#include "path-walk.h"
|
||||||
#include "progress.h"
|
#include "progress.h"
|
||||||
@@ -202,13 +204,19 @@ struct ref_stats {
|
|||||||
size_t others;
|
size_t others;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct object_stats {
|
struct object_values {
|
||||||
size_t tags;
|
size_t tags;
|
||||||
size_t commits;
|
size_t commits;
|
||||||
size_t trees;
|
size_t trees;
|
||||||
size_t blobs;
|
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 repo_structure {
|
||||||
struct ref_stats refs;
|
struct ref_stats refs;
|
||||||
struct object_stats objects;
|
struct object_stats objects;
|
||||||
@@ -219,6 +227,7 @@ struct stats_table {
|
|||||||
|
|
||||||
int name_col_width;
|
int name_col_width;
|
||||||
int value_col_width;
|
int value_col_width;
|
||||||
|
int unit_col_width;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -226,6 +235,7 @@ struct stats_table {
|
|||||||
*/
|
*/
|
||||||
struct stats_table_entry {
|
struct stats_table_entry {
|
||||||
char *value;
|
char *value;
|
||||||
|
const char *unit;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void stats_table_vaddf(struct stats_table *table,
|
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)
|
if (name_width > table->name_col_width)
|
||||||
table->name_col_width = name_width;
|
table->name_col_width = name_width;
|
||||||
if (entry) {
|
if (!entry)
|
||||||
|
return;
|
||||||
|
if (entry->value) {
|
||||||
int value_width = utf8_strwidth(entry->value);
|
int value_width = utf8_strwidth(entry->value);
|
||||||
if (value_width > table->value_col_width)
|
if (value_width > table->value_col_width)
|
||||||
table->value_col_width = value_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, ...)
|
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;
|
va_list ap;
|
||||||
|
|
||||||
CALLOC_ARRAY(entry, 1);
|
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);
|
va_start(ap, format);
|
||||||
stats_table_vaddf(table, entry, format, ap);
|
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;
|
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,
|
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 object_stats *objects = &stats->objects;
|
||||||
struct ref_stats *refs = &stats->refs;
|
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;
|
size_t ref_total;
|
||||||
|
|
||||||
ref_total = get_total_reference_count(refs);
|
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->remotes, " * %s", _("Remotes"));
|
||||||
stats_table_count_addf(table, refs->others, " * %s", _("Others"));
|
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, "");
|
||||||
stats_table_addf(table, "* %s", _("Reachable objects"));
|
stats_table_addf(table, "* %s", _("Reachable objects"));
|
||||||
stats_table_count_addf(table, object_total, " * %s", _("Count"));
|
stats_table_count_addf(table, object_count_total, " * %s", _("Count"));
|
||||||
stats_table_count_addf(table, objects->commits, " * %s", _("Commits"));
|
stats_table_count_addf(table, objects->type_counts.commits,
|
||||||
stats_table_count_addf(table, objects->trees, " * %s", _("Trees"));
|
" * %s", _("Commits"));
|
||||||
stats_table_count_addf(table, objects->blobs, " * %s", _("Blobs"));
|
stats_table_count_addf(table, objects->type_counts.trees,
|
||||||
stats_table_count_addf(table, objects->tags, " * %s", _("Tags"));
|
" * %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)
|
static void stats_table_print_structure(const struct stats_table *table)
|
||||||
{
|
{
|
||||||
const char *name_col_title = _("Repository structure");
|
const char *name_col_title = _("Repository structure");
|
||||||
const char *value_col_title = _("Value");
|
const char *value_col_title = _("Value");
|
||||||
int name_col_width = utf8_strwidth(name_col_title);
|
int title_name_width = utf8_strwidth(name_col_title);
|
||||||
int value_col_width = utf8_strwidth(value_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 string_list_item *item;
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
|
||||||
if (table->name_col_width > name_col_width)
|
if (title_name_width > name_col_width)
|
||||||
name_col_width = table->name_col_width;
|
name_col_width = title_name_width;
|
||||||
if (table->value_col_width > value_col_width)
|
if (title_value_width > value_col_width + unit_col_width + 1)
|
||||||
value_col_width = table->value_col_width;
|
value_col_width = title_value_width - unit_col_width;
|
||||||
|
|
||||||
strbuf_addstr(&buf, "| ");
|
strbuf_addstr(&buf, "| ");
|
||||||
strbuf_utf8_align(&buf, ALIGN_LEFT, name_col_width, name_col_title);
|
strbuf_utf8_align(&buf, ALIGN_LEFT, name_col_width, name_col_title);
|
||||||
strbuf_addstr(&buf, " | ");
|
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, " |");
|
strbuf_addstr(&buf, " |");
|
||||||
printf("%s\n", buf.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++)
|
for (int i = 0; i < name_col_width; i++)
|
||||||
putchar('-');
|
putchar('-');
|
||||||
printf(" | ");
|
printf(" | ");
|
||||||
for (int i = 0; i < value_col_width; i++)
|
for (int i = 0; i < value_col_width + unit_col_width + 1; i++)
|
||||||
putchar('-');
|
putchar('-');
|
||||||
printf(" |\n");
|
printf(" |\n");
|
||||||
|
|
||||||
for_each_string_list_item(item, &table->rows) {
|
for_each_string_list_item(item, &table->rows) {
|
||||||
struct stats_table_entry *entry = item->util;
|
struct stats_table_entry *entry = item->util;
|
||||||
const char *value = "";
|
const char *value = "";
|
||||||
|
const char *unit = "";
|
||||||
|
|
||||||
if (entry) {
|
if (entry) {
|
||||||
struct stats_table_entry *entry = item->util;
|
struct stats_table_entry *entry = item->util;
|
||||||
value = entry->value;
|
value = entry->value;
|
||||||
|
if (entry->unit)
|
||||||
|
unit = entry->unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
strbuf_reset(&buf);
|
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_utf8_align(&buf, ALIGN_LEFT, name_col_width, item->string);
|
||||||
strbuf_addstr(&buf, " | ");
|
strbuf_addstr(&buf, " | ");
|
||||||
strbuf_utf8_align(&buf, ALIGN_RIGHT, value_col_width, value);
|
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, " |");
|
strbuf_addstr(&buf, " |");
|
||||||
printf("%s\n", buf.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);
|
(uintmax_t)stats->refs.others, value_delim);
|
||||||
|
|
||||||
printf("objects.commits.count%c%" PRIuMAX "%c", key_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,
|
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,
|
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,
|
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);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
@@ -460,6 +548,7 @@ static void structure_count_references(struct ref_stats *stats,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct count_objects_data {
|
struct count_objects_data {
|
||||||
|
struct object_database *odb;
|
||||||
struct object_stats *stats;
|
struct object_stats *stats;
|
||||||
struct progress *progress;
|
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 count_objects_data *data = cb_data;
|
||||||
struct object_stats *stats = data->stats;
|
struct object_stats *stats = data->stats;
|
||||||
|
size_t inflated_total = 0;
|
||||||
|
size_t disk_total = 0;
|
||||||
size_t object_count;
|
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) {
|
switch (type) {
|
||||||
case OBJ_TAG:
|
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;
|
break;
|
||||||
case OBJ_COMMIT:
|
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;
|
break;
|
||||||
case OBJ_TREE:
|
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;
|
break;
|
||||||
case OBJ_BLOB:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
BUG("invalid object type");
|
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);
|
display_progress(data->progress, object_count);
|
||||||
|
|
||||||
return 0;
|
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 path_walk_info info = PATH_WALK_INFO_INIT;
|
||||||
struct count_objects_data data = {
|
struct count_objects_data data = {
|
||||||
|
.odb = repo->objects,
|
||||||
.stats = stats,
|
.stats = stats,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
110
strbuf.c
110
strbuf.c
@@ -836,47 +836,83 @@ void strbuf_addstr_urlencode(struct strbuf *sb, const char *s,
|
|||||||
strbuf_add_urlencode(sb, s, strlen(s), allow_unencoded_fn);
|
strbuf_add_urlencode(sb, s, strlen(s), allow_unencoded_fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void strbuf_humanise(struct strbuf *buf, off_t bytes,
|
void humanise_count(size_t count, char **value, const char **unit)
|
||||||
int humanise_rate)
|
|
||||||
{
|
{
|
||||||
if (bytes > 1 << 30) {
|
if (count >= 1000000000) {
|
||||||
strbuf_addf(buf,
|
size_t x = count + 5000000; /* for rounding */
|
||||||
humanise_rate == 0 ?
|
*value = xstrfmt(_("%u.%2.2u"), (unsigned)(x / 1000000000),
|
||||||
/* TRANSLATORS: IEC 80000-13:2008 gibibyte */
|
(unsigned)(x % 1000000000 / 10000000));
|
||||||
_("%u.%2.2u GiB") :
|
/* TRANSLATORS: SI decimal prefix symbol for 10^9 */
|
||||||
/* TRANSLATORS: IEC 80000-13:2008 gibibyte/second */
|
*unit = _("G");
|
||||||
_("%u.%2.2u GiB/s"),
|
} else if (count >= 1000000) {
|
||||||
(unsigned)(bytes >> 30),
|
size_t x = count + 5000; /* for rounding */
|
||||||
(unsigned)(bytes & ((1 << 30) - 1)) / 10737419);
|
*value = xstrfmt(_("%u.%2.2u"), (unsigned)(x / 1000000),
|
||||||
} else if (bytes > 1 << 20) {
|
(unsigned)(x % 1000000 / 10000));
|
||||||
unsigned x = bytes + 5243; /* for rounding */
|
/* TRANSLATORS: SI decimal prefix symbol for 10^6 */
|
||||||
strbuf_addf(buf,
|
*unit = _("M");
|
||||||
humanise_rate == 0 ?
|
} else if (count >= 1000) {
|
||||||
/* TRANSLATORS: IEC 80000-13:2008 mebibyte */
|
size_t x = count + 5; /* for rounding */
|
||||||
_("%u.%2.2u MiB") :
|
*value = xstrfmt(_("%u.%2.2u"), (unsigned)(x / 1000),
|
||||||
/* TRANSLATORS: IEC 80000-13:2008 mebibyte/second */
|
(unsigned)(x % 1000 / 10));
|
||||||
_("%u.%2.2u MiB/s"),
|
/* TRANSLATORS: SI decimal prefix symbol for 10^3 */
|
||||||
x >> 20, ((x & ((1 << 20) - 1)) * 100) >> 20);
|
*unit = _("k");
|
||||||
} else if (bytes > 1 << 10) {
|
|
||||||
unsigned x = bytes + 5; /* for rounding */
|
|
||||||
strbuf_addf(buf,
|
|
||||||
humanise_rate == 0 ?
|
|
||||||
/* TRANSLATORS: IEC 80000-13:2008 kibibyte */
|
|
||||||
_("%u.%2.2u KiB") :
|
|
||||||
/* TRANSLATORS: IEC 80000-13:2008 kibibyte/second */
|
|
||||||
_("%u.%2.2u KiB/s"),
|
|
||||||
x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10);
|
|
||||||
} else {
|
} else {
|
||||||
strbuf_addf(buf,
|
*value = xstrfmt("%u", (unsigned)count);
|
||||||
humanise_rate == 0 ?
|
*unit = NULL;
|
||||||
/* TRANSLATORS: IEC 80000-13:2008 byte */
|
|
||||||
Q_("%u byte", "%u bytes", bytes) :
|
|
||||||
/* TRANSLATORS: IEC 80000-13:2008 byte/second */
|
|
||||||
Q_("%u byte/s", "%u bytes/s", bytes),
|
|
||||||
(unsigned)bytes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void humanise_bytes(off_t bytes, char **value, const char **unit,
|
||||||
|
unsigned flags)
|
||||||
|
{
|
||||||
|
int humanise_rate = flags & HUMANISE_RATE;
|
||||||
|
|
||||||
|
if (bytes > 1 << 30) {
|
||||||
|
*value = xstrfmt(_("%u.%2.2u"), (unsigned)(bytes >> 30),
|
||||||
|
(unsigned)(bytes & ((1 << 30) - 1)) / 10737419);
|
||||||
|
/* TRANSLATORS: IEC 80000-13:2008 gibibyte/second and gibibyte */
|
||||||
|
*unit = humanise_rate ? _("GiB/s") : _("GiB");
|
||||||
|
} else if (bytes > 1 << 20) {
|
||||||
|
unsigned x = bytes + 5243; /* for rounding */
|
||||||
|
*value = xstrfmt(_("%u.%2.2u"), x >> 20,
|
||||||
|
((x & ((1 << 20) - 1)) * 100) >> 20);
|
||||||
|
/* TRANSLATORS: IEC 80000-13:2008 mebibyte/second and mebibyte */
|
||||||
|
*unit = humanise_rate ? _("MiB/s") : _("MiB");
|
||||||
|
} else if (bytes > 1 << 10) {
|
||||||
|
unsigned x = bytes + 5; /* for rounding */
|
||||||
|
*value = xstrfmt(_("%u.%2.2u"), x >> 10,
|
||||||
|
((x & ((1 << 10) - 1)) * 100) >> 10);
|
||||||
|
/* TRANSLATORS: IEC 80000-13:2008 kibibyte/second and kibibyte */
|
||||||
|
*unit = humanise_rate ? _("KiB/s") : _("KiB");
|
||||||
|
} else {
|
||||||
|
*value = xstrfmt("%u", (unsigned)bytes);
|
||||||
|
if (flags & HUMANISE_COMPACT)
|
||||||
|
/* TRANSLATORS: IEC 80000-13:2008 byte/second and byte */
|
||||||
|
*unit = humanise_rate ? _("B/s") : _("B");
|
||||||
|
else
|
||||||
|
*unit = humanise_rate ?
|
||||||
|
/* TRANSLATORS: IEC 80000-13:2008 byte/second */
|
||||||
|
Q_("byte/s", "bytes/s", bytes) :
|
||||||
|
/* TRANSLATORS: IEC 80000-13:2008 byte */
|
||||||
|
Q_("byte", "bytes", bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void strbuf_humanise(struct strbuf *buf, off_t bytes, unsigned flags)
|
||||||
|
{
|
||||||
|
char *value;
|
||||||
|
const char *unit;
|
||||||
|
|
||||||
|
humanise_bytes(bytes, &value, &unit, flags);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TRANSLATORS: The first argument is the number string. The second
|
||||||
|
* argument is the unit string (i.e. "12.34 MiB/s").
|
||||||
|
*/
|
||||||
|
strbuf_addf(buf, _("%s %s"), value, unit);
|
||||||
|
free(value);
|
||||||
|
}
|
||||||
|
|
||||||
void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes)
|
void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes)
|
||||||
{
|
{
|
||||||
strbuf_humanise(buf, bytes, 0);
|
strbuf_humanise(buf, bytes, 0);
|
||||||
@@ -884,7 +920,7 @@ void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes)
|
|||||||
|
|
||||||
void strbuf_humanise_rate(struct strbuf *buf, off_t bytes)
|
void strbuf_humanise_rate(struct strbuf *buf, off_t bytes)
|
||||||
{
|
{
|
||||||
strbuf_humanise(buf, bytes, 1);
|
strbuf_humanise(buf, bytes, HUMANISE_RATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int printf_ln(const char *fmt, ...)
|
int printf_ln(const char *fmt, ...)
|
||||||
|
|||||||
25
strbuf.h
25
strbuf.h
@@ -367,6 +367,31 @@ void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src);
|
|||||||
*/
|
*/
|
||||||
void strbuf_add_percentencode(struct strbuf *dst, const char *src, int flags);
|
void strbuf_add_percentencode(struct strbuf *dst, const char *src, int flags);
|
||||||
|
|
||||||
|
enum humanise_flags {
|
||||||
|
/*
|
||||||
|
* Use rate based units for humanised values.
|
||||||
|
*/
|
||||||
|
HUMANISE_RATE = (1 << 0),
|
||||||
|
/*
|
||||||
|
* Use compact "B" unit symbol instead of "byte/bytes" for humanised
|
||||||
|
* values.
|
||||||
|
*/
|
||||||
|
HUMANISE_COMPACT = (1 << 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the given byte size into a downscaled human-readable value and
|
||||||
|
* corresponding unit as two separate strings.
|
||||||
|
*/
|
||||||
|
void humanise_bytes(off_t bytes, char **value, const char **unit,
|
||||||
|
unsigned flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the given count into a downscaled human-readable value and
|
||||||
|
* corresponding unit as two separate strings.
|
||||||
|
*/
|
||||||
|
void humanise_count(size_t count, char **value, const char **unit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append the given byte size as a human-readable string (i.e. 12.23 KiB,
|
* Append the given byte size as a human-readable string (i.e. 12.23 KiB,
|
||||||
* 3.50 MiB).
|
* 3.50 MiB).
|
||||||
|
|||||||
@@ -603,7 +603,12 @@ int cmd__simple_ipc(int argc, const char **argv)
|
|||||||
OPT_INTEGER(0, "bytecount", &cl_args.bytecount, N_("number of bytes")),
|
OPT_INTEGER(0, "bytecount", &cl_args.bytecount, N_("number of bytes")),
|
||||||
OPT_INTEGER(0, "batchsize", &cl_args.batchsize, N_("number of requests per thread")),
|
OPT_INTEGER(0, "batchsize", &cl_args.batchsize, N_("number of requests per thread")),
|
||||||
|
|
||||||
OPT_STRING(0, "byte", &bytevalue, N_("byte"), N_("ballast character")),
|
/*
|
||||||
|
* The "byte" string here is not marked for translation and
|
||||||
|
* instead relies on translation in strbuf.c:humanise_bytes() to
|
||||||
|
* avoid conflict with the plural form.
|
||||||
|
*/
|
||||||
|
OPT_STRING(0, "byte", &bytevalue, "byte", N_("ballast character")),
|
||||||
OPT_STRING(0, "token", &cl_args.token, N_("token"), N_("command token to send to the server")),
|
OPT_STRING(0, "token", &cl_args.token, N_("token"), N_("command token to send to the server")),
|
||||||
|
|
||||||
OPT_END()
|
OPT_END()
|
||||||
|
|||||||
@@ -4,27 +4,54 @@ test_description='test git repo structure'
|
|||||||
|
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
object_type_disk_usage() {
|
||||||
|
disk_usage_opt="--disk-usage"
|
||||||
|
|
||||||
|
if test "$2" = "true"
|
||||||
|
then
|
||||||
|
disk_usage_opt="--disk-usage=human"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$1" = "all"
|
||||||
|
then
|
||||||
|
git rev-list --all --objects $disk_usage_opt
|
||||||
|
else
|
||||||
|
git rev-list --all --objects $disk_usage_opt \
|
||||||
|
--filter=object:type=$1 --filter-provided-objects
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
test_expect_success 'empty repository' '
|
test_expect_success 'empty repository' '
|
||||||
test_when_finished "rm -rf repo" &&
|
test_when_finished "rm -rf repo" &&
|
||||||
git init repo &&
|
git init repo &&
|
||||||
(
|
(
|
||||||
cd repo &&
|
cd repo &&
|
||||||
cat >expect <<-\EOF &&
|
cat >expect <<-\EOF &&
|
||||||
| Repository structure | Value |
|
| Repository structure | Value |
|
||||||
| -------------------- | ----- |
|
| -------------------- | ------ |
|
||||||
| * References | |
|
| * References | |
|
||||||
| * Count | 0 |
|
| * Count | 0 |
|
||||||
| * Branches | 0 |
|
| * Branches | 0 |
|
||||||
| * Tags | 0 |
|
| * Tags | 0 |
|
||||||
| * Remotes | 0 |
|
| * Remotes | 0 |
|
||||||
| * Others | 0 |
|
| * Others | 0 |
|
||||||
| | |
|
| | |
|
||||||
| * Reachable objects | |
|
| * Reachable objects | |
|
||||||
| * Count | 0 |
|
| * Count | 0 |
|
||||||
| * Commits | 0 |
|
| * Commits | 0 |
|
||||||
| * Trees | 0 |
|
| * Trees | 0 |
|
||||||
| * Blobs | 0 |
|
| * Blobs | 0 |
|
||||||
| * Tags | 0 |
|
| * Tags | 0 |
|
||||||
|
| * Inflated size | 0 B |
|
||||||
|
| * Commits | 0 B |
|
||||||
|
| * Trees | 0 B |
|
||||||
|
| * Blobs | 0 B |
|
||||||
|
| * Tags | 0 B |
|
||||||
|
| * Disk size | 0 B |
|
||||||
|
| * Commits | 0 B |
|
||||||
|
| * Trees | 0 B |
|
||||||
|
| * Blobs | 0 B |
|
||||||
|
| * Tags | 0 B |
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git repo structure >out 2>err &&
|
git repo structure >out 2>err &&
|
||||||
@@ -34,12 +61,12 @@ test_expect_success 'empty repository' '
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'repository with references and objects' '
|
test_expect_success SHA1 'repository with references and objects' '
|
||||||
test_when_finished "rm -rf repo" &&
|
test_when_finished "rm -rf repo" &&
|
||||||
git init repo &&
|
git init repo &&
|
||||||
(
|
(
|
||||||
cd repo &&
|
cd repo &&
|
||||||
test_commit_bulk 42 &&
|
test_commit_bulk 1005 &&
|
||||||
git tag -a foo -m bar &&
|
git tag -a foo -m bar &&
|
||||||
|
|
||||||
oid="$(git rev-parse HEAD)" &&
|
oid="$(git rev-parse HEAD)" &&
|
||||||
@@ -48,22 +75,35 @@ test_expect_success 'repository with references and objects' '
|
|||||||
# Also creates a commit, tree, and blob.
|
# Also creates a commit, tree, and blob.
|
||||||
git notes add -m foo &&
|
git notes add -m foo &&
|
||||||
|
|
||||||
cat >expect <<-\EOF &&
|
# The tags disk size is handled specially due to the
|
||||||
| Repository structure | Value |
|
# git-rev-list(1) --disk-usage=human option printing the full
|
||||||
| -------------------- | ----- |
|
# "byte/bytes" unit string instead of just "B".
|
||||||
| * References | |
|
cat >expect <<-EOF &&
|
||||||
| * Count | 4 |
|
| Repository structure | Value |
|
||||||
| * Branches | 1 |
|
| -------------------- | ---------- |
|
||||||
| * Tags | 1 |
|
| * References | |
|
||||||
| * Remotes | 1 |
|
| * Count | 4 |
|
||||||
| * Others | 1 |
|
| * Branches | 1 |
|
||||||
| | |
|
| * Tags | 1 |
|
||||||
| * Reachable objects | |
|
| * Remotes | 1 |
|
||||||
| * Count | 130 |
|
| * Others | 1 |
|
||||||
| * Commits | 43 |
|
| | |
|
||||||
| * Trees | 43 |
|
| * Reachable objects | |
|
||||||
| * Blobs | 43 |
|
| * Count | 3.02 k |
|
||||||
| * Tags | 1 |
|
| * Commits | 1.01 k |
|
||||||
|
| * Trees | 1.01 k |
|
||||||
|
| * Blobs | 1.01 k |
|
||||||
|
| * Tags | 1 |
|
||||||
|
| * Inflated size | 16.03 MiB |
|
||||||
|
| * Commits | 217.92 KiB |
|
||||||
|
| * Trees | 15.81 MiB |
|
||||||
|
| * Blobs | 11.68 KiB |
|
||||||
|
| * Tags | 132 B |
|
||||||
|
| * Disk size | $(object_type_disk_usage all true) |
|
||||||
|
| * Commits | $(object_type_disk_usage commit true) |
|
||||||
|
| * Trees | $(object_type_disk_usage tree true) |
|
||||||
|
| * Blobs | $(object_type_disk_usage blob true) |
|
||||||
|
| * Tags | $(object_type_disk_usage tag) B |
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git repo structure >out 2>err &&
|
git repo structure >out 2>err &&
|
||||||
@@ -73,7 +113,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" &&
|
test_when_finished "rm -rf repo" &&
|
||||||
git init repo &&
|
git init repo &&
|
||||||
(
|
(
|
||||||
@@ -81,7 +121,7 @@ test_expect_success 'keyvalue and nul format' '
|
|||||||
test_commit_bulk 42 &&
|
test_commit_bulk 42 &&
|
||||||
git tag -a foo -m bar &&
|
git tag -a foo -m bar &&
|
||||||
|
|
||||||
cat >expect <<-\EOF &&
|
cat >expect <<-EOF &&
|
||||||
references.branches.count=1
|
references.branches.count=1
|
||||||
references.tags.count=1
|
references.tags.count=1
|
||||||
references.remotes.count=0
|
references.remotes.count=0
|
||||||
@@ -90,6 +130,14 @@ test_expect_success 'keyvalue and nul format' '
|
|||||||
objects.trees.count=42
|
objects.trees.count=42
|
||||||
objects.blobs.count=42
|
objects.blobs.count=42
|
||||||
objects.tags.count=1
|
objects.tags.count=1
|
||||||
|
objects.commits.inflated_size=9225
|
||||||
|
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
|
EOF
|
||||||
|
|
||||||
git repo structure --format=keyvalue >out 2>err &&
|
git repo structure --format=keyvalue >out 2>err &&
|
||||||
|
|||||||
Reference in New Issue
Block a user