fetch: align all "remote -> local" output

We do align "remote -> local" output by allocating 10 columns to "remote". That produces aligned output only for short refs. An extra pass is performed to find the longest remote ref name (that does not produce a line longer than terminal width) to produce better aligned output. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Jul 1, 2016 at 18:03 UTC 6bc91f23a6e14d540ab6950b438d40cf678143f0
2 files changed +60 -2
builtin/fetch.c
+45 -2
@@ -15,6 +15,7 @@
15 #include "submodule.h"
16 #include "connected.h"
17 #include "argv-array.h"
18 +#include "utf8.h"
19
20 static const char * const builtin_fetch_usage[] = {
21 N_("git fetch [<options>] [<repository> [<refspec>...]]"),
@@ -449,14 +450,54 @@ fail:
450 : STORE_REF_ERROR_OTHER;
451 }
452
452 -#define REFCOL_WIDTH 10
453 +static int refcol_width = 10;
454 +
455 +static void adjust_refcol_width(const struct ref *ref)
456 +{
457 + int max, rlen, llen, len;
458 +
459 + /* uptodate lines are only shown on high verbosity level */
460 + if (!verbosity && !oidcmp(&ref->peer_ref->old_oid, &ref->old_oid))
461 + return;
462 +
463 + max = term_columns();
464 + rlen = utf8_strwidth(prettify_refname(ref->name));
465 + llen = utf8_strwidth(prettify_refname(ref->peer_ref->name));
466 +
467 + /*
468 + * rough estimation to see if the output line is too long and
469 + * should not be counted (we can't do precise calculation
470 + * anyway because we don't know if the error explanation part
471 + * will be printed in update_local_ref)
472 + */
473 + len = 21 /* flag and summary */ + rlen + 4 /* -> */ + llen;
474 + if (len >= max)
475 + return;
476 +
477 + if (refcol_width < rlen)
478 + refcol_width = rlen;
479 +}
480 +
481 +static void prepare_format_display(struct ref *ref_map)
482 +{
483 + struct ref *rm;
484 +
485 + for (rm = ref_map; rm; rm = rm->next) {
486 + if (rm->status == REF_STATUS_REJECT_SHALLOW ||
487 + !rm->peer_ref ||
488 + !strcmp(rm->name, "HEAD"))
489 + continue;
490 +
491 + adjust_refcol_width(rm);
492 + }
493 +}
494
495 static void format_display(struct strbuf *display, char code,
496 const char *summary, const char *error,
497 const char *remote, const char *local)
498 {
499 strbuf_addf(display, "%c %-*s ", code, TRANSPORT_SUMMARY(summary));
459 - strbuf_addf(display, "%-*s -> %s", REFCOL_WIDTH, remote, local);
500 + strbuf_addf(display, "%-*s -> %s", refcol_width, remote, local);
501 if (error)
502 strbuf_addf(display, " (%s)", error);
503 }
@@ -618,6 +659,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
659 goto abort;
660 }
661
662 + prepare_format_display(ref_map);
663 +
664 /*
665 * We do a pass for each fetch_head_status type in their enum order, so
666 * merged entries are written before not-for-merge. That lets readers
t/t5510-fetch.sh
+15
@@ -688,4 +688,19 @@ test_expect_success 'fetching with auto-gc does not lock up' '
688 )
689 '
690
691 +test_expect_success 'fetch aligned output' '
692 + git clone . full-output &&
693 + test_commit looooooooooooong-tag &&
694 + (
695 + cd full-output &&
696 + git fetch origin 2>&1 | \
697 + grep -e "->" | cut -c 22- >../actual
698 + ) &&
699 + cat >expect <<-\EOF &&
700 + master -> origin/master
701 + looooooooooooong-tag -> looooooooooooong-tag
702 + EOF
703 + test_cmp expect actual
704 +'
705 +
706 test_done