fetch: move reference width calculation into `display_state`

In order to print references in proper columns we need to calculate the width of the reference column before starting to print the references. This is done with the help of a global variable `refcol_width`. Refactor the code to instead use a new structure `display_state` that contains the computed width and plumb it through the stack as required. This is only the first step towards de-globalizing the state required to print references. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Mar 20, 2023 at 13:35 UTC ce9636d645714974e5f7e1e9abc65fa57186b147
1 file changed +65 -46
builtin/fetch.c
+65 -46
@@ -47,6 +47,10 @@ enum {
47 TAGS_SET = 2
48 };
49
50 +struct display_state {
51 + int refcol_width;
52 +};
53 +
54 static int fetch_prune_config = -1; /* unspecified */
55 static int fetch_show_forced_updates = 1;
56 static uint64_t forced_updates_ms = 0;
@@ -741,16 +745,15 @@ out:
745 return ret;
746 }
747
744 -static int refcol_width = 10;
748 static int compact_format;
749
747 -static void adjust_refcol_width(const struct ref *ref)
750 +static int refcol_width(const struct ref *ref)
751 {
752 int max, rlen, llen, len;
753
754 /* uptodate lines are only shown on high verbosity level */
755 if (verbosity <= 0 && oideq(&ref->peer_ref->old_oid, &ref->old_oid))
753 - return;
756 + return 0;
757
758 max = term_columns();
759 rlen = utf8_strwidth(prettify_refname(ref->name));
@@ -769,22 +772,18 @@ static void adjust_refcol_width(const struct ref *ref)
772 }
773 len = 21 /* flag and summary */ + rlen + 4 /* -> */ + llen;
774 if (len >= max)
772 - return;
775 + return 0;
776
774 - /*
775 - * Not precise calculation for compact mode because '*' can
776 - * appear on the left hand side of '->' and shrink the column
777 - * back.
778 - */
779 - if (refcol_width < rlen)
780 - refcol_width = rlen;
777 + return rlen;
778 }
779
783 -static void prepare_format_display(struct ref *ref_map)
780 +static void display_state_init(struct display_state *display_state, struct ref *ref_map)
781 {
782 struct ref *rm;
783 const char *format = "full";
784
785 + memset(display_state, 0, sizeof(*display_state));
786 +
787 if (verbosity < 0)
788 return;
789
@@ -797,20 +796,32 @@ static void prepare_format_display(struct ref *ref_map)
796 die(_("invalid value for '%s': '%s'"),
797 "fetch.output", format);
798
799 + display_state->refcol_width = 10;
800 for (rm = ref_map; rm; rm = rm->next) {
801 + int width;
802 +
803 if (rm->status == REF_STATUS_REJECT_SHALLOW ||
804 !rm->peer_ref ||
805 !strcmp(rm->name, "HEAD"))
806 continue;
807
806 - adjust_refcol_width(rm);
808 + width = refcol_width(rm);
809 +
810 + /*
811 + * Not precise calculation for compact mode because '*' can
812 + * appear on the left hand side of '->' and shrink the column
813 + * back.
814 + */
815 + if (display_state->refcol_width < width)
816 + display_state->refcol_width = width;
817 }
818 }
819
810 -static void print_remote_to_local(struct strbuf *display,
820 +static void print_remote_to_local(struct display_state *display_state,
821 + struct strbuf *display_buffer,
822 const char *remote, const char *local)
823 {
813 - strbuf_addf(display, "%-*s -> %s", refcol_width, remote, local);
824 + strbuf_addf(display_buffer, "%-*s -> %s", display_state->refcol_width, remote, local);
825 }
826
827 static int find_and_replace(struct strbuf *haystack,
@@ -840,14 +851,14 @@ static int find_and_replace(struct strbuf *haystack,
851 return 1;
852 }
853
843 -static void print_compact(struct strbuf *display,
854 +static void print_compact(struct display_state *display_state, struct strbuf *display_buffer,
855 const char *remote, const char *local)
856 {
857 struct strbuf r = STRBUF_INIT;
858 struct strbuf l = STRBUF_INIT;
859
860 if (!strcmp(remote, local)) {
850 - strbuf_addf(display, "%-*s -> *", refcol_width, remote);
861 + strbuf_addf(display_buffer, "%-*s -> *", display_state->refcol_width, remote);
862 return;
863 }
864
@@ -856,13 +867,14 @@ static void print_compact(struct strbuf *display,
867
868 if (!find_and_replace(&r, local, "*"))
869 find_and_replace(&l, remote, "*");
859 - print_remote_to_local(display, r.buf, l.buf);
870 + print_remote_to_local(display_state, display_buffer, r.buf, l.buf);
871
872 strbuf_release(&r);
873 strbuf_release(&l);
874 }
875
865 -static void format_display(struct strbuf *display, char code,
876 +static void format_display(struct display_state *display_state,
877 + struct strbuf *display_buffer, char code,
878 const char *summary, const char *error,
879 const char *remote, const char *local,
880 int summary_width)
@@ -874,17 +886,18 @@ static void format_display(struct strbuf *display, char code,
886
887 width = (summary_width + strlen(summary) - gettext_width(summary));
888
877 - strbuf_addf(display, "%c %-*s ", code, width, summary);
889 + strbuf_addf(display_buffer, "%c %-*s ", code, width, summary);
890 if (!compact_format)
879 - print_remote_to_local(display, remote, local);
891 + print_remote_to_local(display_state, display_buffer, remote, local);
892 else
881 - print_compact(display, remote, local);
893 + print_compact(display_state, display_buffer, remote, local);
894 if (error)
883 - strbuf_addf(display, " (%s)", error);
895 + strbuf_addf(display_buffer, " (%s)", error);
896 }
897
898 static int update_local_ref(struct ref *ref,
899 struct ref_transaction *transaction,
900 + struct display_state *display_state,
901 const char *remote, const struct ref *remote_ref,
902 struct strbuf *display, int summary_width)
903 {
@@ -897,7 +910,7 @@ static int update_local_ref(struct ref *ref,
910
911 if (oideq(&ref->old_oid, &ref->new_oid)) {
912 if (verbosity > 0)
900 - format_display(display, '=', _("[up to date]"), NULL,
913 + format_display(display_state, display, '=', _("[up to date]"), NULL,
914 remote, pretty_ref, summary_width);
915 return 0;
916 }
@@ -909,7 +922,7 @@ static int update_local_ref(struct ref *ref,
922 * If this is the head, and it's not okay to update
923 * the head, and the old value of the head isn't empty...
924 */
912 - format_display(display, '!', _("[rejected]"),
925 + format_display(display_state, display, '!', _("[rejected]"),
926 _("can't fetch into checked-out branch"),
927 remote, pretty_ref, summary_width);
928 return 1;
@@ -920,12 +933,13 @@ static int update_local_ref(struct ref *ref,
933 if (force || ref->force) {
934 int r;
935 r = s_update_ref("updating tag", ref, transaction, 0);
923 - format_display(display, r ? '!' : 't', _("[tag update]"),
936 + format_display(display_state, display, r ? '!' : 't', _("[tag update]"),
937 r ? _("unable to update local ref") : NULL,
938 remote, pretty_ref, summary_width);
939 return r;
940 } else {
928 - format_display(display, '!', _("[rejected]"), _("would clobber existing tag"),
941 + format_display(display_state, display, '!', _("[rejected]"),
942 + _("would clobber existing tag"),
943 remote, pretty_ref, summary_width);
944 return 1;
945 }
@@ -957,7 +971,7 @@ static int update_local_ref(struct ref *ref,
971 }
972
973 r = s_update_ref(msg, ref, transaction, 0);
960 - format_display(display, r ? '!' : '*', what,
974 + format_display(display_state, display, r ? '!' : '*', what,
975 r ? _("unable to update local ref") : NULL,
976 remote, pretty_ref, summary_width);
977 return r;
@@ -979,7 +993,7 @@ static int update_local_ref(struct ref *ref,
993 strbuf_addstr(&quickref, "..");
994 strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
995 r = s_update_ref("fast-forward", ref, transaction, 1);
982 - format_display(display, r ? '!' : ' ', quickref.buf,
996 + format_display(display_state, display, r ? '!' : ' ', quickref.buf,
997 r ? _("unable to update local ref") : NULL,
998 remote, pretty_ref, summary_width);
999 strbuf_release(&quickref);
@@ -991,13 +1005,13 @@ static int update_local_ref(struct ref *ref,
1005 strbuf_addstr(&quickref, "...");
1006 strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
1007 r = s_update_ref("forced-update", ref, transaction, 1);
994 - format_display(display, r ? '!' : '+', quickref.buf,
1008 + format_display(display_state, display, r ? '!' : '+', quickref.buf,
1009 r ? _("unable to update local ref") : _("forced update"),
1010 remote, pretty_ref, summary_width);
1011 strbuf_release(&quickref);
1012 return r;
1013 } else {
1000 - format_display(display, '!', _("[rejected]"), _("non-fast-forward"),
1014 + format_display(display_state, display, '!', _("[rejected]"), _("non-fast-forward"),
1015 remote, pretty_ref, summary_width);
1016 return 1;
1017 }
@@ -1108,7 +1122,8 @@ N_("it took %.2f seconds to check forced updates; you can use\n"
1122 "'--no-show-forced-updates' or run 'git config fetch.showForcedUpdates false'\n"
1123 "to avoid this check\n");
1124
1111 -static int store_updated_refs(const char *raw_url, const char *remote_name,
1125 +static int store_updated_refs(struct display_state *display_state,
1126 + const char *raw_url, const char *remote_name,
1127 int connectivity_checked,
1128 struct ref_transaction *transaction, struct ref *ref_map,
1129 struct fetch_head *fetch_head)
@@ -1139,8 +1154,6 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
1154 }
1155 }
1156
1142 - prepare_format_display(ref_map);
1143 -
1157 /*
1158 * We do a pass for each fetch_head_status type in their enum order, so
1159 * merged entries are written before not-for-merge. That lets readers
@@ -1240,7 +1253,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
1253
1254 strbuf_reset(&note);
1255 if (ref) {
1243 - rc |= update_local_ref(ref, transaction, what,
1256 + rc |= update_local_ref(ref, transaction, display_state, what,
1257 rm, &note, summary_width);
1258 free(ref);
1259 } else if (write_fetch_head || dry_run) {
@@ -1249,7 +1262,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
1262 * would be written to FETCH_HEAD, if --dry-run
1263 * is set).
1264 */
1252 - format_display(&note, '*',
1265 + format_display(display_state, &note, '*',
1266 *kind ? kind : "branch", NULL,
1267 *what ? what : "HEAD",
1268 "FETCH_HEAD", summary_width);
@@ -1328,7 +1341,8 @@ static int check_exist_and_connected(struct ref *ref_map)
1341 return check_connected(iterate_ref_map, &rm, &opt);
1342 }
1343
1331 -static int fetch_and_consume_refs(struct transport *transport,
1344 +static int fetch_and_consume_refs(struct display_state *display_state,
1345 + struct transport *transport,
1346 struct ref_transaction *transaction,
1347 struct ref *ref_map,
1348 struct fetch_head *fetch_head)
@@ -1352,7 +1366,7 @@ static int fetch_and_consume_refs(struct transport *transport,
1366 }
1367
1368 trace2_region_enter("fetch", "consume_refs", the_repository);
1355 - ret = store_updated_refs(transport->url, transport->remote->name,
1369 + ret = store_updated_refs(display_state, transport->url, transport->remote->name,
1370 connectivity_checked, transaction, ref_map,
1371 fetch_head);
1372 trace2_region_leave("fetch", "consume_refs", the_repository);
@@ -1362,7 +1376,8 @@ out:
1376 return ret;
1377 }
1378
1365 -static int prune_refs(struct refspec *rs,
1379 +static int prune_refs(struct display_state *display_state,
1380 + struct refspec *rs,
1381 struct ref_transaction *transaction,
1382 struct ref *ref_map,
1383 const char *raw_url)
@@ -1416,7 +1431,7 @@ static int prune_refs(struct refspec *rs,
1431 fprintf(stderr, _("From %.*s\n"), url_len, url);
1432 shown_url = 1;
1433 }
1419 - format_display(&sb, '-', _("[deleted]"), NULL,
1434 + format_display(display_state, &sb, '-', _("[deleted]"), NULL,
1435 _("(none)"), prettify_refname(ref->name),
1436 summary_width);
1437 fprintf(stderr, " %s\n",sb.buf);
@@ -1542,7 +1557,8 @@ static struct transport *prepare_transport(struct remote *remote, int deepen)
1557 return transport;
1558 }
1559
1545 -static int backfill_tags(struct transport *transport,
1560 +static int backfill_tags(struct display_state *display_state,
1561 + struct transport *transport,
1562 struct ref_transaction *transaction,
1563 struct ref *ref_map,
1564 struct fetch_head *fetch_head)
@@ -1566,7 +1582,7 @@ static int backfill_tags(struct transport *transport,
1582 transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, NULL);
1583 transport_set_option(transport, TRANS_OPT_DEPTH, "0");
1584 transport_set_option(transport, TRANS_OPT_DEEPEN_RELATIVE, NULL);
1569 - retcode = fetch_and_consume_refs(transport, transaction, ref_map, fetch_head);
1585 + retcode = fetch_and_consume_refs(display_state, transport, transaction, ref_map, fetch_head);
1586
1587 if (gsecondary) {
1588 transport_disconnect(gsecondary);
@@ -1581,6 +1597,7 @@ static int do_fetch(struct transport *transport,
1597 {
1598 struct ref_transaction *transaction = NULL;
1599 struct ref *ref_map = NULL;
1600 + struct display_state display_state;
1601 int autotags = (transport->remote->fetch_tags == 1);
1602 int retcode = 0;
1603 const struct ref *remote_refs;
@@ -1662,6 +1679,8 @@ static int do_fetch(struct transport *transport,
1679 if (retcode)
1680 goto cleanup;
1681
1682 + display_state_init(&display_state, ref_map);
1683 +
1684 if (atomic_fetch) {
1685 transaction = ref_transaction_begin(&err);
1686 if (!transaction) {
@@ -1679,9 +1698,9 @@ static int do_fetch(struct transport *transport,
1698 * don't care whether --tags was specified.
1699 */
1700 if (rs->nr) {
1682 - retcode = prune_refs(rs, transaction, ref_map, transport->url);
1701 + retcode = prune_refs(&display_state, rs, transaction, ref_map, transport->url);
1702 } else {
1684 - retcode = prune_refs(&transport->remote->fetch,
1703 + retcode = prune_refs(&display_state, &transport->remote->fetch,
1704 transaction, ref_map,
1705 transport->url);
1706 }
@@ -1689,7 +1708,7 @@ static int do_fetch(struct transport *transport,
1708 retcode = 1;
1709 }
1710
1692 - if (fetch_and_consume_refs(transport, transaction, ref_map, &fetch_head)) {
1711 + if (fetch_and_consume_refs(&display_state, transport, transaction, ref_map, &fetch_head)) {
1712 retcode = 1;
1713 goto cleanup;
1714 }
@@ -1711,7 +1730,7 @@ static int do_fetch(struct transport *transport,
1730 * when `--atomic` is passed: in that case we'll abort
1731 * the transaction and don't commit anything.
1732 */
1714 - if (backfill_tags(transport, transaction, tags_ref_map,
1733 + if (backfill_tags(&display_state, transport, transaction, tags_ref_map,
1734 &fetch_head))
1735 retcode = 1;
1736 }