22
33#include "builtin.h"
44#include "config.h"
5+ #include "environment.h"
6+ #include "hex.h"
57#include "object.h"
68#include "odb.h"
9+ #include "object-name.h"
710#include "parse-options.h"
11+ #include "path-walk.h"
812#include "progress.h"
913#include "ref-filter.h"
14+ #include "refs.h"
15+ #include "revision.h"
1016#include "strbuf.h"
1117#include "strvec.h"
18+ #include "tag.h"
1219#include "trace2.h"
1320
1421static const char * const survey_usage [] = {
@@ -46,12 +53,20 @@ struct survey_report_ref_summary {
4653 size_t unknown_nr ;
4754};
4855
56+ struct survey_report_object_summary {
57+ size_t commits_nr ;
58+ size_t tags_nr ;
59+ size_t trees_nr ;
60+ size_t blobs_nr ;
61+ };
62+
4963/**
5064 * This struct contains all of the information that needs to be printed
5165 * at the end of the exploration of the repository and its references.
5266 */
5367struct survey_report {
5468 struct survey_report_ref_summary refs ;
69+ struct survey_report_object_summary reachable_objects ;
5570};
5671
5772struct survey_context {
@@ -74,10 +89,12 @@ struct survey_context {
7489 size_t progress_total ;
7590
7691 struct strvec refs ;
92+ struct ref_array ref_array ;
7793};
7894
7995static void clear_survey_context (struct survey_context * ctx )
8096{
97+ ref_array_clear (& ctx -> ref_array );
8198 strvec_clear (& ctx -> refs );
8299}
83100
@@ -128,10 +145,14 @@ static const size_t section_len = 4 * SECTION_SEGMENT_LEN;
128145static void print_table_title (const char * name , size_t * widths , size_t nr )
129146{
130147 size_t width = 3 * (nr - 1 );
148+ size_t min_width = strlen (name );
131149
132150 for (size_t i = 0 ; i < nr ; i ++ )
133151 width += widths [i ];
134152
153+ if (width < min_width )
154+ width = min_width ;
155+
135156 if (width > section_len )
136157 width = section_len ;
137158
@@ -228,11 +249,43 @@ static void survey_report_plaintext_refs(struct survey_context *ctx)
228249 clear_table (& table );
229250}
230251
252+ static void survey_report_plaintext_reachable_object_summary (struct survey_context * ctx )
253+ {
254+ struct survey_report_object_summary * objs = & ctx -> report .reachable_objects ;
255+ struct survey_table table = SURVEY_TABLE_INIT ;
256+ char * fmt ;
257+
258+ table .table_name = _ ("REACHABLE OBJECT SUMMARY" );
259+
260+ strvec_push (& table .header , _ ("Object Type" ));
261+ strvec_push (& table .header , _ ("Count" ));
262+
263+ fmt = xstrfmt ("%" PRIuMAX "" , (uintmax_t )objs -> tags_nr );
264+ insert_table_rowv (& table , _ ("Tags" ), fmt , NULL );
265+ free (fmt );
266+
267+ fmt = xstrfmt ("%" PRIuMAX "" , (uintmax_t )objs -> commits_nr );
268+ insert_table_rowv (& table , _ ("Commits" ), fmt , NULL );
269+ free (fmt );
270+
271+ fmt = xstrfmt ("%" PRIuMAX "" , (uintmax_t )objs -> trees_nr );
272+ insert_table_rowv (& table , _ ("Trees" ), fmt , NULL );
273+ free (fmt );
274+
275+ fmt = xstrfmt ("%" PRIuMAX "" , (uintmax_t )objs -> blobs_nr );
276+ insert_table_rowv (& table , _ ("Blobs" ), fmt , NULL );
277+ free (fmt );
278+
279+ print_table_plaintext (& table );
280+ clear_table (& table );
281+ }
282+
231283static void survey_report_plaintext (struct survey_context * ctx )
232284{
233285 printf ("GIT SURVEY for \"%s\"\n" , ctx -> repo -> worktree );
234286 printf ("-----------------------------------------------------\n" );
235287 survey_report_plaintext_refs (ctx );
288+ survey_report_plaintext_reachable_object_summary (ctx );
236289}
237290
238291/*
@@ -381,15 +434,13 @@ static void do_load_refs(struct survey_context *ctx,
381434 */
382435static void survey_phase_refs (struct survey_context * ctx )
383436{
384- struct ref_array ref_array = { 0 };
385-
386437 trace2_region_enter ("survey" , "phase/refs" , ctx -> repo );
387- do_load_refs (ctx , & ref_array );
438+ do_load_refs (ctx , & ctx -> ref_array );
388439
389- ctx -> report .refs .refs_nr = ref_array .nr ;
390- for (int i = 0 ; i < ref_array .nr ; i ++ ) {
440+ ctx -> report .refs .refs_nr = ctx -> ref_array .nr ;
441+ for (int i = 0 ; i < ctx -> ref_array .nr ; i ++ ) {
391442 unsigned long size ;
392- struct ref_array_item * item = ref_array .items [i ];
443+ struct ref_array_item * item = ctx -> ref_array .items [i ];
393444
394445 switch (item -> kind ) {
395446 case FILTER_REFS_TAGS :
@@ -419,8 +470,72 @@ static void survey_phase_refs(struct survey_context *ctx)
419470 }
420471
421472 trace2_region_leave ("survey" , "phase/refs" , ctx -> repo );
473+ }
474+
475+ static void increment_object_counts (
476+ struct survey_report_object_summary * summary ,
477+ enum object_type type ,
478+ size_t nr )
479+ {
480+ switch (type ) {
481+ case OBJ_COMMIT :
482+ summary -> commits_nr += nr ;
483+ break ;
422484
423- ref_array_clear (& ref_array );
485+ case OBJ_TREE :
486+ summary -> trees_nr += nr ;
487+ break ;
488+
489+ case OBJ_BLOB :
490+ summary -> blobs_nr += nr ;
491+ break ;
492+
493+ case OBJ_TAG :
494+ summary -> tags_nr += nr ;
495+ break ;
496+
497+ default :
498+ break ;
499+ }
500+ }
501+
502+ static int survey_objects_path_walk_fn (const char * path UNUSED ,
503+ struct oid_array * oids ,
504+ enum object_type type ,
505+ void * data )
506+ {
507+ struct survey_context * ctx = data ;
508+
509+ increment_object_counts (& ctx -> report .reachable_objects ,
510+ type , oids -> nr );
511+
512+ return 0 ;
513+ }
514+
515+ static void survey_phase_objects (struct survey_context * ctx )
516+ {
517+ struct rev_info revs = REV_INFO_INIT ;
518+ struct path_walk_info info = PATH_WALK_INFO_INIT ;
519+ unsigned int add_flags = 0 ;
520+
521+ trace2_region_enter ("survey" , "phase/objects" , ctx -> repo );
522+
523+ info .revs = & revs ;
524+ info .path_fn = survey_objects_path_walk_fn ;
525+ info .path_fn_data = ctx ;
526+
527+ repo_init_revisions (ctx -> repo , & revs , "" );
528+ revs .tag_objects = 1 ;
529+
530+ for (int i = 0 ; i < ctx -> ref_array .nr ; i ++ ) {
531+ struct ref_array_item * item = ctx -> ref_array .items [i ];
532+ add_pending_oid (& revs , NULL , & item -> objectname , add_flags );
533+ }
534+
535+ walk_objects_by_path (& info );
536+
537+ release_revisions (& revs );
538+ trace2_region_leave ("survey" , "phase/objects" , ctx -> repo );
424539}
425540
426541int cmd_survey (int argc , const char * * argv , const char * prefix , struct repository * repo )
@@ -473,6 +588,8 @@ int cmd_survey(int argc, const char **argv, const char *prefix, struct repositor
473588
474589 survey_phase_refs (& ctx );
475590
591+ survey_phase_objects (& ctx );
592+
476593 survey_report_plaintext (& ctx );
477594
478595 clear_survey_context (& ctx );
0 commit comments