Skip to content

Commit 3703b8a

Browse files
jeffhostetlerdscho
authored andcommitted
survey: add commit name-rev lookup to each large_item
Signed-off-by: Jeff Hostetler <[email protected]>
1 parent 64e86d2 commit 3703b8a

File tree

1 file changed

+86
-3
lines changed

1 file changed

+86
-3
lines changed

builtin/survey.c

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "ref-filter.h"
1414
#include "refs.h"
1515
#include "revision.h"
16+
#include "run-command.h"
1617
#include "strbuf.h"
1718
#include "strvec.h"
1819
#include "trace2.h"
@@ -171,6 +172,12 @@ struct large_item {
171172
* order).
172173
*/
173174
struct object_id containing_commit_oid;
175+
176+
/*
177+
* Lookup `containing_commit_oid` using `git name-rev`.
178+
* Lazy allocate this post-treewalk.
179+
*/
180+
struct strbuf name_rev;
174181
};
175182

176183
struct large_item_vec {
@@ -207,8 +214,10 @@ static void free_large_item_vec(struct large_item_vec *vec)
207214
if (!vec)
208215
return;
209216

210-
for (size_t k = 0; k < vec->nr_items; k++)
217+
for (size_t k = 0; k < vec->nr_items; k++) {
211218
strbuf_release(&vec->items[k].name);
219+
strbuf_release(&vec->items[k].name_rev);
220+
}
212221

213222
free(vec->dimension_label);
214223
free(vec->item_label);
@@ -243,6 +252,9 @@ static void maybe_insert_large_item(struct large_item_vec *vec,
243252
* The last large_item in the vector is about to be
244253
* overwritten by the previous one during the shift.
245254
* Steal its allocated strbuf and reuse it.
255+
*
256+
* We can ignore .name_rev because it will not be
257+
* allocated until after the treewalk.
246258
*/
247259
strbuf_release(&vec->items[vec->nr_items - 1].name);
248260

@@ -764,7 +776,7 @@ static void survey_report_largest_vec(struct large_item_vec *vec)
764776
return;
765777

766778
table.table_name = vec->dimension_label;
767-
strvec_pushl(&table.header, "Size", "OID", "Name", "Commit", NULL);
779+
strvec_pushl(&table.header, "Size", "OID", "Name", "Commit", "Name-Rev", NULL);
768780

769781
for (size_t k = 0; k < vec->nr_items; k++) {
770782
struct large_item *pk = &vec->items[k];
@@ -775,6 +787,7 @@ static void survey_report_largest_vec(struct large_item_vec *vec)
775787
insert_table_rowv(&table, size.buf, oid_to_hex(&pk->oid), pk->name.buf,
776788
is_null_oid(&pk->containing_commit_oid) ?
777789
"" : oid_to_hex(&pk->containing_commit_oid),
790+
pk->name_rev.len ? pk->name_rev.buf : "",
778791
NULL);
779792
}
780793
}
@@ -1126,6 +1139,73 @@ static void do_load_refs(struct survey_context *ctx,
11261139
ref_sorting_release(sorting);
11271140
}
11281141

1142+
/*
1143+
* Try to run `git name-rev` on each of the containing-commit-oid's
1144+
* in this large-item-vec to get a pretty name for each OID. Silently
1145+
* ignore errors if it fails because this info is nice to have but not
1146+
* essential.
1147+
*/
1148+
static void large_item_vec_lookup_name_rev(struct survey_context *ctx,
1149+
struct large_item_vec *vec)
1150+
{
1151+
struct child_process cp = CHILD_PROCESS_INIT;
1152+
struct strbuf in = STRBUF_INIT;
1153+
struct strbuf out = STRBUF_INIT;
1154+
const char *line;
1155+
size_t k;
1156+
1157+
if (!vec || !vec->nr_items)
1158+
return;
1159+
1160+
ctx->progress_total += vec->nr_items;
1161+
display_progress(ctx->progress, ctx->progress_total);
1162+
1163+
for (k = 0; k < vec->nr_items; k++)
1164+
strbuf_addf(&in, "%s\n", oid_to_hex(&vec->items[k].containing_commit_oid));
1165+
1166+
cp.git_cmd = 1;
1167+
strvec_pushl(&cp.args, "name-rev", "--name-only", "--annotate-stdin", NULL);
1168+
if (pipe_command(&cp, in.buf, in.len, &out, 0, NULL, 0)) {
1169+
strbuf_release(&in);
1170+
strbuf_release(&out);
1171+
return;
1172+
}
1173+
1174+
line = out.buf;
1175+
k = 0;
1176+
while (*line) {
1177+
const char *eol = strchrnul(line, '\n');
1178+
1179+
strbuf_init(&vec->items[k].name_rev, 0);
1180+
strbuf_add(&vec->items[k].name_rev, line, (eol - line));
1181+
1182+
line = eol + 1;
1183+
k++;
1184+
}
1185+
1186+
strbuf_release(&in);
1187+
strbuf_release(&out);
1188+
}
1189+
1190+
static void do_lookup_name_rev(struct survey_context *ctx)
1191+
{
1192+
if (ctx->opts.show_progress) {
1193+
ctx->progress_total = 0;
1194+
ctx->progress = start_progress(ctx->repo, _("Resolving name-revs..."), 0);
1195+
}
1196+
1197+
large_item_vec_lookup_name_rev(ctx, ctx->report.reachable_objects.commits.vec_largest_by_nr_parents);
1198+
large_item_vec_lookup_name_rev(ctx, ctx->report.reachable_objects.commits.vec_largest_by_size_bytes);
1199+
1200+
large_item_vec_lookup_name_rev(ctx, ctx->report.reachable_objects.trees.vec_largest_by_nr_entries);
1201+
large_item_vec_lookup_name_rev(ctx, ctx->report.reachable_objects.trees.vec_largest_by_size_bytes);
1202+
1203+
large_item_vec_lookup_name_rev(ctx, ctx->report.reachable_objects.blobs.vec_largest_by_size_bytes);
1204+
1205+
if (ctx->opts.show_progress)
1206+
stop_progress(&ctx->progress);
1207+
}
1208+
11291209
/*
11301210
* The REFS phase:
11311211
*
@@ -1481,7 +1561,10 @@ static void survey_phase_objects(struct survey_context *ctx)
14811561

14821562
release_revisions(&revs);
14831563
trace2_region_leave("survey", "phase/objects", ctx->repo);
1484-
}
1564+
1565+
trace2_region_enter("survey", "phase/namerev", the_repository);
1566+
do_lookup_name_rev(ctx);
1567+
trace2_region_enter("survey", "phase/namerev", the_repository);}
14851568

14861569
int cmd_survey(int argc, const char **argv, const char *prefix, struct repository *repo)
14871570
{

0 commit comments

Comments
 (0)