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
176183struct 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 *
@@ -1482,7 +1562,10 @@ static void survey_phase_objects(struct survey_context *ctx)
14821562
14831563 release_revisions (& revs );
14841564 trace2_region_leave ("survey" , "phase/objects" , ctx -> repo );
1485- }
1565+
1566+ trace2_region_enter ("survey" , "phase/namerev" , the_repository );
1567+ do_lookup_name_rev (ctx );
1568+ trace2_region_enter ("survey" , "phase/namerev" , the_repository );}
14861569
14871570int cmd_survey (int argc , const char * * argv , const char * prefix , struct repository * repo )
14881571{
0 commit comments