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
}
@@ -1126,6 +1139,73 @@ static void do_load_refs(struct survey_context *ctx,
1126
1139
ref_sorting_release (sorting );
1127
1140
}
1128
1141
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
+
1129
1209
/*
1130
1210
* The REFS phase:
1131
1211
*
@@ -1481,7 +1561,10 @@ static void survey_phase_objects(struct survey_context *ctx)
1481
1561
1482
1562
release_revisions (& revs );
1483
1563
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 );}
1485
1568
1486
1569
int cmd_survey (int argc , const char * * argv , const char * prefix , struct repository * repo )
1487
1570
{
0 commit comments