1515#include "revision.h"
1616#include "strbuf.h"
1717#include "strvec.h"
18- #include "tag.h"
1918#include "trace2.h"
20- #include "color.h"
2119
2220static const char * const survey_usage [] = {
2321 N_ ("(EXPERIMENTAL!) git survey <options>" ),
@@ -53,6 +51,22 @@ struct survey_report_ref_summary {
5351 size_t tags_annotated_nr ;
5452 size_t others_nr ;
5553 size_t unknown_nr ;
54+
55+ size_t cnt_symref ;
56+
57+ size_t cnt_packed ;
58+ size_t cnt_loose ;
59+
60+ /*
61+ * Measure the length of the refnames. We can look for
62+ * potential platform limits. The partial sums may help us
63+ * estimate the size of a haves/wants conversation, since each
64+ * refname and a SHA must be transmitted.
65+ */
66+ size_t len_max_local_refname ;
67+ size_t len_sum_local_refnames ;
68+ size_t len_max_remote_refname ;
69+ size_t len_sum_remote_refnames ;
5670};
5771
5872struct survey_report_object_summary {
@@ -380,6 +394,42 @@ static void survey_report_plaintext_refs(struct survey_context *ctx)
380394 free (fmt );
381395 }
382396
397+ /*
398+ * SymRefs are somewhat orthogonal to the above classification (e.g.
399+ * "HEAD" --> detached and "refs/remotes/origin/HEAD" --> remote) so the
400+ * above classified counts will already include them, but it is less
401+ * confusing to display them here than to create a whole new section.
402+ */
403+ if (ctx -> report .refs .cnt_symref ) {
404+ char * fmt = xstrfmt ("%" PRIuMAX "" , (uintmax_t )refs -> cnt_symref );
405+ insert_table_rowv (& table , _ ("Symbolic refs" ), fmt , NULL );
406+ free (fmt );
407+ }
408+
409+ if (ctx -> report .refs .cnt_loose || ctx -> report .refs .cnt_packed ) {
410+ char * fmt = xstrfmt ("%" PRIuMAX "" , (uintmax_t )refs -> cnt_loose );
411+ insert_table_rowv (& table , _ ("Loose refs" ), fmt , NULL );
412+ free (fmt );
413+ fmt = xstrfmt ("%" PRIuMAX "" , (uintmax_t )refs -> cnt_packed );
414+ insert_table_rowv (& table , _ ("Packed refs" ), fmt , NULL );
415+ free (fmt );
416+ }
417+
418+ if (ctx -> report .refs .len_max_local_refname || ctx -> report .refs .len_max_remote_refname ) {
419+ char * fmt = xstrfmt ("%" PRIuMAX "" , (uintmax_t )refs -> len_max_local_refname );
420+ insert_table_rowv (& table , _ ("Max local refname length" ), fmt , NULL );
421+ free (fmt );
422+ fmt = xstrfmt ("%" PRIuMAX "" , (uintmax_t )refs -> len_sum_local_refnames );
423+ insert_table_rowv (& table , _ ("Sum local refnames length" ), fmt , NULL );
424+ free (fmt );
425+ fmt = xstrfmt ("%" PRIuMAX "" , (uintmax_t )refs -> len_max_remote_refname );
426+ insert_table_rowv (& table , _ ("Max remote refname length" ), fmt , NULL );
427+ free (fmt );
428+ fmt = xstrfmt ("%" PRIuMAX "" , (uintmax_t )refs -> len_sum_remote_refnames );
429+ insert_table_rowv (& table , _ ("Sum remote refnames length" ), fmt , NULL );
430+ free (fmt );
431+ }
432+
383433 print_table_plaintext (& table );
384434 clear_table (& table );
385435}
@@ -638,6 +688,7 @@ static void survey_phase_refs(struct survey_context *ctx)
638688 for (int i = 0 ; i < ctx -> ref_array .nr ; i ++ ) {
639689 unsigned long size ;
640690 struct ref_array_item * item = ctx -> ref_array .items [i ];
691+ size_t len = strlen (item -> refname );
641692
642693 switch (item -> kind ) {
643694 case FILTER_REFS_TAGS :
@@ -664,6 +715,33 @@ static void survey_phase_refs(struct survey_context *ctx)
664715 ctx -> report .refs .unknown_nr ++ ;
665716 break ;
666717 }
718+
719+ /*
720+ * SymRefs are somewhat orthogonal to the above
721+ * classification (e.g. "HEAD" --> detached
722+ * and "refs/remotes/origin/HEAD" --> remote) so
723+ * our totals will already include them.
724+ */
725+ if (item -> flag & REF_ISSYMREF )
726+ ctx -> report .refs .cnt_symref ++ ;
727+
728+ /*
729+ * Where/how is the ref stored in GITDIR.
730+ */
731+ if (item -> flag & REF_ISPACKED )
732+ ctx -> report .refs .cnt_packed ++ ;
733+ else
734+ ctx -> report .refs .cnt_loose ++ ;
735+
736+ if (item -> kind == FILTER_REFS_REMOTES ) {
737+ ctx -> report .refs .len_sum_remote_refnames += len ;
738+ if (len > ctx -> report .refs .len_max_remote_refname )
739+ ctx -> report .refs .len_max_remote_refname = len ;
740+ } else {
741+ ctx -> report .refs .len_sum_local_refnames += len ;
742+ if (len > ctx -> report .refs .len_max_local_refname )
743+ ctx -> report .refs .len_max_local_refname = len ;
744+ }
667745 }
668746
669747 trace2_region_leave ("survey" , "phase/refs" , ctx -> repo );
0 commit comments