diff --git a/builtin/survey.c b/builtin/survey.c index 0ed0bed41585b2..2a03140241c191 100644 --- a/builtin/survey.c +++ b/builtin/survey.c @@ -1352,12 +1352,257 @@ static void survey_print_results_json(void) jw_release(&jw); } +static void fmt_txt_line(struct strbuf *buf, int indent, const char *txt) +{ + if (indent) + strbuf_addchars(buf, ' ', indent); + + strbuf_addstr(buf, txt); + + strbuf_addch(buf, '\n'); +} + +static void fmt_ref_row(struct strbuf *buf, + int indent, + const char *label, + uint64_t value, + const char *footnote) +{ + int column0 = 50; + + if (indent) + strbuf_addchars(buf, ' ', indent); + + strbuf_addf(buf, "%-*s : %14"PRIu64, + column0 - indent, label, + value); + if (footnote && *footnote) + strbuf_addf(buf, " : %s", footnote); + + strbuf_addch(buf, '\n'); +} + +static void pretty_print_survey_hdr(void) +{ + struct strbuf buf = STRBUF_INIT; + int indent = 0; + int k; + + const char *intro[] = { + "", + "================================================================", + "Git Survey Results", + "================================================================", + "", + NULL + }; + + k = 0; + while (intro[k]) + fmt_txt_line(&buf, indent, intro[k++]); + + /* + * NEEDSWORK: Consider adding information about the repo pathname, + * the date, command line args, git version, etc. + */ + + fwrite(buf.buf, 1, buf.len, stdout); + strbuf_release(&buf); +} + +/* + * Pretty print information on the set of REFS that we examined. + * + * NEEDSWORK: Create footnotes when there are large numbers of REFS + * and annotate the various row items. We probably want more than one + * footnote and try to capture various dimensions of scale, such as + * one for remote refs talking about push/fetch overhead. Or one for + * lots of loose refs and associated overhead. Then add a footnote + * table/list below the row detail to explain them. Or possibly just + * have a fixed set of footnote numbers (like ERRNO error codes) and + * refer them to the man-page. + */ +static void pretty_print_refs(int indent) +{ + struct survey_refs_wanted *prw = &survey_opts.refs; + struct survey_stats_refs *prs = &survey_stats.refs; + struct strbuf buf = STRBUF_INIT; + int indent1 = indent + 4; + int indent2 = indent + 8; + int indent3 = indent + 12; + int k; + + const char *intro[] = { + "", + "REFS", + "----", + "", + "The number of refs affects the performance of various Git commands,", + "such as 'git fetch'.", + "", + NULL + }; + + k = 0; + while (intro[k]) + fmt_txt_line(&buf, indent, intro[k++]); + + fmt_ref_row(&buf, indent, "Total Number of Refs", prs->cnt_total, NULL); + + strbuf_addch(&buf, '\n'); + fmt_txt_line(&buf, indent1, "References by Type"); + + if (prw->want_remotes && prs->cnt_remotes) + fmt_ref_row(&buf, indent2, "Remote Tracking Branches", prs->cnt_remotes, NULL); + + if (prw->want_branches && prs->cnt_branches) + fmt_ref_row(&buf, indent2, "Branches", prs->cnt_branches, NULL); + if (prw->want_tags && prs->cnt_lightweight_tags) + fmt_ref_row(&buf, indent2, "Tags (Lightweight)", prs->cnt_lightweight_tags, NULL); + if (prw->want_tags && prs->cnt_annotated_tags) + fmt_ref_row(&buf, indent2, "Tags (Annotated)", prs->cnt_annotated_tags, NULL); + if (prw->want_detached && prs->cnt_detached) + fmt_ref_row(&buf, indent2, "Detached", prs->cnt_detached, NULL); + if (prw->want_other && prs->cnt_other) + fmt_ref_row(&buf, indent2, "Other (Notes and Stashes)", prs->cnt_other, NULL); + + if (prs->cnt_symref) + fmt_ref_row(&buf, indent2, "Symbolic Refs (like 'HEAD')", prs->cnt_symref, NULL); + + if ((prw->want_prefetch && prs->cnt_prefetch) || + (prw->want_pull && prs->cnt_pull)) { + + strbuf_addch(&buf, '\n'); + fmt_txt_line(&buf, indent2, "Custom Local Branches Namespaces"); + + if (prw->want_prefetch && prs->cnt_prefetch) + fmt_ref_row(&buf, indent3, "prefetch", prs->cnt_prefetch, NULL); + if (prw->want_pull && prs->cnt_pull) + fmt_ref_row(&buf, indent3, "pull", prs->cnt_pull, NULL); + } + + if (survey_opts.verbose) { + strbuf_addch(&buf, '\n'); + fmt_txt_line(&buf, indent1, "References by Storage Location"); + fmt_ref_row(&buf, indent2, "Loose", prs->cnt_loose, NULL); + fmt_ref_row(&buf, indent2, "Packed", prs->cnt_packed, NULL); + + strbuf_addch(&buf, '\n'); + fmt_txt_line(&buf, indent1, "String Length of Refnames"); + if (prs->len_sum_remote_refnames) { + fmt_txt_line(&buf, indent2, "Remote Refs"); + fmt_ref_row(&buf, indent3, "Max", prs->len_max_remote_refname, NULL); + fmt_ref_row(&buf, indent3, "Sum", prs->len_sum_remote_refnames, NULL); + } + if (prs->len_sum_local_refnames) { + fmt_txt_line(&buf, indent2, "Local Refs"); + fmt_ref_row(&buf, indent3, "Max", prs->len_max_local_refname, NULL); + fmt_ref_row(&buf, indent3, "Sum", prs->len_sum_local_refnames, NULL); + } + + /* + * NEEDSWORK: Do we want to print the set of "refs/" + * patterns that we requested to be in the set? + */ + } + + /* + * NEEDSWORK: Print a table of the footnotes when present. + */ + + fwrite(buf.buf, 1, buf.len, stdout); + strbuf_release(&buf); +} + +static void pretty_print_commits(int indent) +{ + struct strbuf buf = STRBUF_INIT; + int k; + + const char *intro[] = { + "", + "COMMITS", + "-------", + "", + NULL + }; + + k = 0; + while (intro[k]) + fmt_txt_line(&buf, indent, intro[k++]); + + /* + * NEEDSWORK: TODO + */ + + fwrite(buf.buf, 1, buf.len, stdout); + strbuf_release(&buf); +} + +static void pretty_print_trees(int indent) +{ + struct strbuf buf = STRBUF_INIT; + int k; + + const char *intro[] = { + "", + "TREES", + "-----", + "", + NULL + }; + + k = 0; + while (intro[k]) + fmt_txt_line(&buf, indent, intro[k++]); + + /* + * NEEDSWORK: TODO + */ + + fwrite(buf.buf, 1, buf.len, stdout); + strbuf_release(&buf); +} + +static void pretty_print_blobs(int indent) +{ + struct strbuf buf = STRBUF_INIT; + int k; + + const char *intro[] = { + "", + "BLOBS", + "-----", + "", + NULL + }; + + k = 0; + while (intro[k]) + fmt_txt_line(&buf, indent, intro[k++]); + + /* + * NEEDSWORK: TODO + */ + + fwrite(buf.buf, 1, buf.len, stdout); + strbuf_release(&buf); +} + /* * Print all of the stats that we have collected in a more pretty format. */ static void survey_print_results_pretty(void) { - printf("TODO....\n"); + pretty_print_survey_hdr(); + pretty_print_refs(0); + pretty_print_commits(0); + pretty_print_trees(0); + pretty_print_blobs(0); + + /* + * NEEDSWORK: what else should be dump? + */ } int cmd_survey(int argc, const char **argv, const char *prefix)