2
2
3
3
#include "builtin.h"
4
4
#include "config.h"
5
+ #include "environment.h"
6
+ #include "hex.h"
5
7
#include "object.h"
8
+ #include "object-name.h"
6
9
#include "object-store-ll.h"
7
10
#include "parse-options.h"
11
+ #include "path-walk.h"
8
12
#include "progress.h"
9
13
#include "ref-filter.h"
14
+ #include "refs.h"
15
+ #include "revision.h"
10
16
#include "strbuf.h"
11
17
#include "strvec.h"
18
+ #include "tag.h"
12
19
#include "trace2.h"
13
20
14
21
static const char * const survey_usage [] = {
@@ -46,12 +53,20 @@ struct survey_report_ref_summary {
46
53
size_t unknown_nr ;
47
54
};
48
55
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
+
49
63
/**
50
64
* This struct contains all of the information that needs to be printed
51
65
* at the end of the exploration of the repository and its references.
52
66
*/
53
67
struct survey_report {
54
68
struct survey_report_ref_summary refs ;
69
+ struct survey_report_object_summary reachable_objects ;
55
70
};
56
71
57
72
struct survey_context {
@@ -74,10 +89,12 @@ struct survey_context {
74
89
size_t progress_total ;
75
90
76
91
struct strvec refs ;
92
+ struct ref_array ref_array ;
77
93
};
78
94
79
95
static void clear_survey_context (struct survey_context * ctx )
80
96
{
97
+ ref_array_clear (& ctx -> ref_array );
81
98
strvec_clear (& ctx -> refs );
82
99
}
83
100
@@ -128,10 +145,14 @@ static const size_t section_len = 4 * SECTION_SEGMENT_LEN;
128
145
static void print_table_title (const char * name , size_t * widths , size_t nr )
129
146
{
130
147
size_t width = 3 * (nr - 1 );
148
+ size_t min_width = strlen (name );
131
149
132
150
for (size_t i = 0 ; i < nr ; i ++ )
133
151
width += widths [i ];
134
152
153
+ if (width < min_width )
154
+ width = min_width ;
155
+
135
156
if (width > section_len )
136
157
width = section_len ;
137
158
@@ -228,11 +249,43 @@ static void survey_report_plaintext_refs(struct survey_context *ctx)
228
249
clear_table (& table );
229
250
}
230
251
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
+
231
283
static void survey_report_plaintext (struct survey_context * ctx )
232
284
{
233
285
printf ("GIT SURVEY for \"%s\"\n" , ctx -> repo -> worktree );
234
286
printf ("-----------------------------------------------------\n" );
235
287
survey_report_plaintext_refs (ctx );
288
+ survey_report_plaintext_reachable_object_summary (ctx );
236
289
}
237
290
238
291
/*
@@ -380,15 +433,13 @@ static void do_load_refs(struct survey_context *ctx,
380
433
*/
381
434
static void survey_phase_refs (struct survey_context * ctx )
382
435
{
383
- struct ref_array ref_array = { 0 };
384
-
385
436
trace2_region_enter ("survey" , "phase/refs" , ctx -> repo );
386
- do_load_refs (ctx , & ref_array );
437
+ do_load_refs (ctx , & ctx -> ref_array );
387
438
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 ++ ) {
390
441
unsigned long size ;
391
- struct ref_array_item * item = ref_array .items [i ];
442
+ struct ref_array_item * item = ctx -> ref_array .items [i ];
392
443
393
444
switch (item -> kind ) {
394
445
case FILTER_REFS_TAGS :
@@ -418,8 +469,72 @@ static void survey_phase_refs(struct survey_context *ctx)
418
469
}
419
470
420
471
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 ;
421
483
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 );
423
538
}
424
539
425
540
int 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
472
587
473
588
survey_phase_refs (& ctx );
474
589
590
+ survey_phase_objects (& ctx );
591
+
475
592
survey_report_plaintext (& ctx );
476
593
477
594
clear_survey_context (& ctx );
0 commit comments