13
13
#include "ref-filter.h"
14
14
#include "refs.h"
15
15
#include "revision.h"
16
+ #include "run-command.h"
16
17
#include "strbuf.h"
17
18
#include "strvec.h"
18
19
#include "trace2.h"
@@ -171,6 +172,12 @@ struct large_item {
171
172
* order).
172
173
*/
173
174
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 ;
174
181
};
175
182
176
183
struct large_item_vec {
@@ -207,8 +214,10 @@ static void free_large_item_vec(struct large_item_vec *vec)
207
214
if (!vec )
208
215
return ;
209
216
210
- for (size_t k = 0 ; k < vec -> nr_items ; k ++ )
217
+ for (size_t k = 0 ; k < vec -> nr_items ; k ++ ) {
211
218
strbuf_release (& vec -> items [k ].name );
219
+ strbuf_release (& vec -> items [k ].name_rev );
220
+ }
212
221
213
222
free (vec -> dimension_label );
214
223
free (vec -> item_label );
@@ -243,6 +252,9 @@ static void maybe_insert_large_item(struct large_item_vec *vec,
243
252
* The last large_item in the vector is about to be
244
253
* overwritten by the previous one during the shift.
245
254
* 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.
246
258
*/
247
259
strbuf_release (& vec -> items [vec -> nr_items - 1 ].name );
248
260
@@ -764,7 +776,7 @@ static void survey_report_largest_vec(struct large_item_vec *vec)
764
776
return ;
765
777
766
778
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 );
768
780
769
781
for (size_t k = 0 ; k < vec -> nr_items ; k ++ ) {
770
782
struct large_item * pk = & vec -> items [k ];
@@ -775,6 +787,7 @@ static void survey_report_largest_vec(struct large_item_vec *vec)
775
787
insert_table_rowv (& table , size .buf , oid_to_hex (& pk -> oid ), pk -> name .buf ,
776
788
is_null_oid (& pk -> containing_commit_oid ) ?
777
789
"" : oid_to_hex (& pk -> containing_commit_oid ),
790
+ pk -> name_rev .len ? pk -> name_rev .buf : "" ,
778
791
NULL );
779
792
}
780
793
}
@@ -1125,6 +1138,73 @@ static void do_load_refs(struct survey_context *ctx,
1125
1138
ref_sorting_release (sorting );
1126
1139
}
1127
1140
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
+
1128
1208
/*
1129
1209
* The REFS phase:
1130
1210
*
@@ -1478,7 +1558,10 @@ static void survey_phase_objects(struct survey_context *ctx)
1478
1558
1479
1559
release_revisions (& revs );
1480
1560
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 );}
1482
1565
1483
1566
int cmd_survey (int argc , const char * * argv , const char * prefix , struct repository * repo )
1484
1567
{
0 commit comments