Skip to content

Commit ba10649

Browse files
jeffhostetlerdscho
authored andcommitted
survey: add commit name-rev lookup to each large_item
Signed-off-by: Jeff Hostetler <jeffhostetler@github.com>
1 parent 0fb037f commit ba10649

File tree

1 file changed

+86
-3
lines changed

1 file changed

+86
-3
lines changed

Diff for: builtin/survey.c

+86-3
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
}
@@ -1125,6 +1138,73 @@ static void do_load_refs(struct survey_context *ctx,
11251138
ref_sorting_release(sorting);
11261139
}
11271140

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

14791559
release_revisions(&revs);
14801560
trace2_region_leave("survey", "phase/objects", ctx->repo);
1481-
}
1561+
1562+
trace2_region_enter("survey", "phase/namerev", the_repository);
1563+
do_lookup_name_rev(ctx);
1564+
trace2_region_enter("survey", "phase/namerev", the_repository);}
14821565

14831566
int cmd_survey(int argc, const char **argv, const char *prefix, struct repository *repo)
14841567
{

0 commit comments

Comments
 (0)