Skip to content

Commit 5473132

Browse files
jltoblergitster
authored andcommitted
builtin/repo: humanise count values in structure output
The table output format for the git-repo(1) structure subcommand is used by default and intended to provide output to users in a human-friendly manner. When the reference/object count values in a repository are large, it becomes more cumbersome for users to read the values. For larger values, update the table output format to instead produce more human-friendly count values that are scaled down with the appropriate unit prefix. Output for the keyvalue and nul formats remains unchanged. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent ce849b1 commit 5473132

4 files changed

Lines changed: 91 additions & 41 deletions

File tree

builtin/repo.c

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -223,13 +223,15 @@ struct stats_table {
223223

224224
int name_col_width;
225225
int value_col_width;
226+
int unit_col_width;
226227
};
227228

228229
/*
229230
* Holds column data that gets stored for each row.
230231
*/
231232
struct stats_table_entry {
232233
char *value;
234+
const char *unit;
233235
};
234236

235237
static void stats_table_vaddf(struct stats_table *table,
@@ -250,11 +252,18 @@ static void stats_table_vaddf(struct stats_table *table,
250252

251253
if (name_width > table->name_col_width)
252254
table->name_col_width = name_width;
253-
if (entry) {
255+
if (!entry)
256+
return;
257+
if (entry->value) {
254258
int value_width = utf8_strwidth(entry->value);
255259
if (value_width > table->value_col_width)
256260
table->value_col_width = value_width;
257261
}
262+
if (entry->unit) {
263+
int unit_width = utf8_strwidth(entry->unit);
264+
if (unit_width > table->unit_col_width)
265+
table->unit_col_width = unit_width;
266+
}
258267
}
259268

260269
static void stats_table_addf(struct stats_table *table, const char *format, ...)
@@ -273,7 +282,7 @@ static void stats_table_count_addf(struct stats_table *table, size_t value,
273282
va_list ap;
274283

275284
CALLOC_ARRAY(entry, 1);
276-
entry->value = xstrfmt("%" PRIuMAX, (uintmax_t)value);
285+
humanise_count(value, &entry->value, &entry->unit);
277286

278287
va_start(ap, format);
279288
stats_table_vaddf(table, entry, format, ap);
@@ -324,45 +333,54 @@ static void stats_table_print_structure(const struct stats_table *table)
324333
{
325334
const char *name_col_title = _("Repository structure");
326335
const char *value_col_title = _("Value");
327-
int name_col_width = utf8_strwidth(name_col_title);
328-
int value_col_width = utf8_strwidth(value_col_title);
336+
int title_name_width = utf8_strwidth(name_col_title);
337+
int title_value_width = utf8_strwidth(value_col_title);
338+
int name_col_width = table->name_col_width;
339+
int value_col_width = table->value_col_width;
340+
int unit_col_width = table->unit_col_width;
329341
struct string_list_item *item;
330342
struct strbuf buf = STRBUF_INIT;
331343

332-
if (table->name_col_width > name_col_width)
333-
name_col_width = table->name_col_width;
334-
if (table->value_col_width > value_col_width)
335-
value_col_width = table->value_col_width;
344+
if (title_name_width > name_col_width)
345+
name_col_width = title_name_width;
346+
if (title_value_width > value_col_width + unit_col_width + 1)
347+
value_col_width = title_value_width - unit_col_width;
336348

337349
strbuf_addstr(&buf, "| ");
338350
strbuf_utf8_align(&buf, ALIGN_LEFT, name_col_width, name_col_title);
339351
strbuf_addstr(&buf, " | ");
340-
strbuf_utf8_align(&buf, ALIGN_LEFT, value_col_width, value_col_title);
352+
strbuf_utf8_align(&buf, ALIGN_LEFT,
353+
value_col_width + unit_col_width + 1, value_col_title);
341354
strbuf_addstr(&buf, " |");
342355
printf("%s\n", buf.buf);
343356

344357
printf("| ");
345358
for (int i = 0; i < name_col_width; i++)
346359
putchar('-');
347360
printf(" | ");
348-
for (int i = 0; i < value_col_width; i++)
361+
for (int i = 0; i < value_col_width + unit_col_width + 1; i++)
349362
putchar('-');
350363
printf(" |\n");
351364

352365
for_each_string_list_item(item, &table->rows) {
353366
struct stats_table_entry *entry = item->util;
354367
const char *value = "";
368+
const char *unit = "";
355369

356370
if (entry) {
357371
struct stats_table_entry *entry = item->util;
358372
value = entry->value;
373+
if (entry->unit)
374+
unit = entry->unit;
359375
}
360376

361377
strbuf_reset(&buf);
362378
strbuf_addstr(&buf, "| ");
363379
strbuf_utf8_align(&buf, ALIGN_LEFT, name_col_width, item->string);
364380
strbuf_addstr(&buf, " | ");
365381
strbuf_utf8_align(&buf, ALIGN_RIGHT, value_col_width, value);
382+
strbuf_addch(&buf, ' ');
383+
strbuf_utf8_align(&buf, ALIGN_LEFT, unit_col_width, unit);
366384
strbuf_addstr(&buf, " |");
367385
printf("%s\n", buf.buf);
368386
}

strbuf.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,32 @@ void strbuf_addstr_urlencode(struct strbuf *sb, const char *s,
836836
strbuf_add_urlencode(sb, s, strlen(s), allow_unencoded_fn);
837837
}
838838

839+
void humanise_count(size_t count, char **value, const char **unit)
840+
{
841+
if (count >= 1000000000) {
842+
size_t x = count + 5000000; /* for rounding */
843+
*value = xstrfmt(_("%u.%2.2u"), (unsigned)(x / 1000000000),
844+
(unsigned)(x % 1000000000 / 10000000));
845+
/* TRANSLATORS: SI decimal prefix symbol for 10^9 */
846+
*unit = _("G");
847+
} else if (count >= 1000000) {
848+
size_t x = count + 5000; /* for rounding */
849+
*value = xstrfmt(_("%u.%2.2u"), (unsigned)(x / 1000000),
850+
(unsigned)(x % 1000000 / 10000));
851+
/* TRANSLATORS: SI decimal prefix symbol for 10^6 */
852+
*unit = _("M");
853+
} else if (count >= 1000) {
854+
size_t x = count + 5; /* for rounding */
855+
*value = xstrfmt(_("%u.%2.2u"), (unsigned)(x / 1000),
856+
(unsigned)(x % 1000 / 10));
857+
/* TRANSLATORS: SI decimal prefix symbol for 10^3 */
858+
*unit = _("k");
859+
} else {
860+
*value = xstrfmt("%u", (unsigned)count);
861+
*unit = NULL;
862+
}
863+
}
864+
839865
void humanise_bytes(off_t bytes, char **value, const char **unit,
840866
unsigned flags)
841867
{

strbuf.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,12 @@ enum humanise_flags {
381381
void humanise_bytes(off_t bytes, char **value, const char **unit,
382382
unsigned flags);
383383

384+
/**
385+
* Converts the given count into a downscaled human-readable value and
386+
* corresponding unit as two separate strings.
387+
*/
388+
void humanise_count(size_t count, char **value, const char **unit);
389+
384390
/**
385391
* Append the given byte size as a human-readable string (i.e. 12.23 KiB,
386392
* 3.50 MiB).

t/t1901-repo-structure.sh

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,21 @@ test_expect_success 'empty repository' '
1010
(
1111
cd repo &&
1212
cat >expect <<-\EOF &&
13-
| Repository structure | Value |
14-
| -------------------- | ----- |
15-
| * References | |
16-
| * Count | 0 |
17-
| * Branches | 0 |
18-
| * Tags | 0 |
19-
| * Remotes | 0 |
20-
| * Others | 0 |
21-
| | |
22-
| * Reachable objects | |
23-
| * Count | 0 |
24-
| * Commits | 0 |
25-
| * Trees | 0 |
26-
| * Blobs | 0 |
27-
| * Tags | 0 |
13+
| Repository structure | Value |
14+
| -------------------- | ------ |
15+
| * References | |
16+
| * Count | 0 |
17+
| * Branches | 0 |
18+
| * Tags | 0 |
19+
| * Remotes | 0 |
20+
| * Others | 0 |
21+
| | |
22+
| * Reachable objects | |
23+
| * Count | 0 |
24+
| * Commits | 0 |
25+
| * Trees | 0 |
26+
| * Blobs | 0 |
27+
| * Tags | 0 |
2828
EOF
2929
3030
git repo structure >out 2>err &&
@@ -39,7 +39,7 @@ test_expect_success 'repository with references and objects' '
3939
git init repo &&
4040
(
4141
cd repo &&
42-
test_commit_bulk 42 &&
42+
test_commit_bulk 1005 &&
4343
git tag -a foo -m bar &&
4444
4545
oid="$(git rev-parse HEAD)" &&
@@ -49,21 +49,21 @@ test_expect_success 'repository with references and objects' '
4949
git notes add -m foo &&
5050
5151
cat >expect <<-\EOF &&
52-
| Repository structure | Value |
53-
| -------------------- | ----- |
54-
| * References | |
55-
| * Count | 4 |
56-
| * Branches | 1 |
57-
| * Tags | 1 |
58-
| * Remotes | 1 |
59-
| * Others | 1 |
60-
| | |
61-
| * Reachable objects | |
62-
| * Count | 130 |
63-
| * Commits | 43 |
64-
| * Trees | 43 |
65-
| * Blobs | 43 |
66-
| * Tags | 1 |
52+
| Repository structure | Value |
53+
| -------------------- | ------ |
54+
| * References | |
55+
| * Count | 4 |
56+
| * Branches | 1 |
57+
| * Tags | 1 |
58+
| * Remotes | 1 |
59+
| * Others | 1 |
60+
| | |
61+
| * Reachable objects | |
62+
| * Count | 3.02 k |
63+
| * Commits | 1.01 k |
64+
| * Trees | 1.01 k |
65+
| * Blobs | 1.01 k |
66+
| * Tags | 1 |
6767
EOF
6868
6969
git repo structure >out 2>err &&

0 commit comments

Comments
 (0)