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}
@@ -637,6 +687,7 @@ static void survey_phase_refs(struct survey_context *ctx)
637687 for (int i = 0 ; i < ctx -> ref_array .nr ; i ++ ) {
638688 unsigned long size ;
639689 struct ref_array_item * item = ctx -> ref_array .items [i ];
690+ size_t len = strlen (item -> refname );
640691
641692 switch (item -> kind ) {
642693 case FILTER_REFS_TAGS :
@@ -663,6 +714,33 @@ static void survey_phase_refs(struct survey_context *ctx)
663714 ctx -> report .refs .unknown_nr ++ ;
664715 break ;
665716 }
717+
718+ /*
719+ * SymRefs are somewhat orthogonal to the above
720+ * classification (e.g. "HEAD" --> detached
721+ * and "refs/remotes/origin/HEAD" --> remote) so
722+ * our totals will already include them.
723+ */
724+ if (item -> flag & REF_ISSYMREF )
725+ ctx -> report .refs .cnt_symref ++ ;
726+
727+ /*
728+ * Where/how is the ref stored in GITDIR.
729+ */
730+ if (item -> flag & REF_ISPACKED )
731+ ctx -> report .refs .cnt_packed ++ ;
732+ else
733+ ctx -> report .refs .cnt_loose ++ ;
734+
735+ if (item -> kind == FILTER_REFS_REMOTES ) {
736+ ctx -> report .refs .len_sum_remote_refnames += len ;
737+ if (len > ctx -> report .refs .len_max_remote_refname )
738+ ctx -> report .refs .len_max_remote_refname = len ;
739+ } else {
740+ ctx -> report .refs .len_sum_local_refnames += len ;
741+ if (len > ctx -> report .refs .len_max_local_refname )
742+ ctx -> report .refs .len_max_local_refname = len ;
743+ }
666744 }
667745
668746 trace2_region_leave ("survey" , "phase/refs" , ctx -> repo );
0 commit comments