22
33#include "builtin.h"
44#include "config.h"
5+ #include "environment.h"
6+ #include "hex.h"
57#include "object.h"
8+ #include "object-name.h"
69#include "object-store-ll.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/*
@@ -380,15 +433,13 @@ static void do_load_refs(struct survey_context *ctx,
380433 */
381434static void survey_phase_refs (struct survey_context * ctx )
382435{
383- struct ref_array ref_array = { 0 };
384-
385436 trace2_region_enter ("survey" , "phase/refs" , ctx -> repo );
386- do_load_refs (ctx , & ref_array );
437+ do_load_refs (ctx , & ctx -> ref_array );
387438
388- ctx -> report .refs .refs_nr = ref_array .nr ;
389- for (size_t i = 0 ; i < ref_array .nr ; i ++ ) {
439+ ctx -> report .refs .refs_nr = ctx -> ref_array .nr ;
440+ for (size_t i = 0 ; i < ctx -> ref_array .nr ; i ++ ) {
390441 unsigned long size ;
391- struct ref_array_item * item = ref_array .items [i ];
442+ struct ref_array_item * item = ctx -> ref_array .items [i ];
392443
393444 switch (item -> kind ) {
394445 case FILTER_REFS_TAGS :
@@ -418,8 +469,72 @@ static void survey_phase_refs(struct survey_context *ctx)
418469 }
419470
420471 trace2_region_leave ("survey" , "phase/refs" , ctx -> repo );
472+ }
473+
474+ static void increment_object_counts (
475+ struct survey_report_object_summary * summary ,
476+ enum object_type type ,
477+ size_t nr )
478+ {
479+ switch (type ) {
480+ case OBJ_COMMIT :
481+ summary -> commits_nr += nr ;
482+ break ;
421483
422- ref_array_clear (& ref_array );
484+ case OBJ_TREE :
485+ summary -> trees_nr += nr ;
486+ break ;
487+
488+ case OBJ_BLOB :
489+ summary -> blobs_nr += nr ;
490+ break ;
491+
492+ case OBJ_TAG :
493+ summary -> tags_nr += nr ;
494+ break ;
495+
496+ default :
497+ break ;
498+ }
499+ }
500+
501+ static int survey_objects_path_walk_fn (const char * path ,
502+ struct oid_array * oids ,
503+ enum object_type type ,
504+ void * data )
505+ {
506+ struct survey_context * ctx = data ;
507+
508+ increment_object_counts (& ctx -> report .reachable_objects ,
509+ type , oids -> nr );
510+
511+ return 0 ;
512+ }
513+
514+ static void survey_phase_objects (struct survey_context * ctx )
515+ {
516+ struct rev_info revs = REV_INFO_INIT ;
517+ struct path_walk_info info = PATH_WALK_INFO_INIT ;
518+ unsigned int add_flags = 0 ;
519+
520+ trace2_region_enter ("survey" , "phase/objects" , ctx -> repo );
521+
522+ info .revs = & revs ;
523+ info .path_fn = survey_objects_path_walk_fn ;
524+ info .path_fn_data = ctx ;
525+
526+ repo_init_revisions (ctx -> repo , & revs , "" );
527+ revs .tag_objects = 1 ;
528+
529+ for (size_t i = 0 ; i < ctx -> ref_array .nr ; i ++ ) {
530+ struct ref_array_item * item = ctx -> ref_array .items [i ];
531+ add_pending_oid (& revs , NULL , & item -> objectname , add_flags );
532+ }
533+
534+ walk_objects_by_path (& info );
535+
536+ release_revisions (& revs );
537+ trace2_region_leave ("survey" , "phase/objects" , ctx -> repo );
423538}
424539
425540int cmd_survey (int argc , const char * * argv , const char * prefix , struct repository * repo )
@@ -472,6 +587,8 @@ int cmd_survey(int argc, const char **argv, const char *prefix, struct repositor
472587
473588 survey_phase_refs (& ctx );
474589
590+ survey_phase_objects (& ctx );
591+
475592 survey_report_plaintext (& ctx );
476593
477594 clear_survey_context (& ctx );
0 commit comments