summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2016-07-01 16:03:31 (GMT)
committerJunio C Hamano <gitster@pobox.com>2016-07-06 18:48:25 (GMT)
commitbc437d10202c015a5733f706dc44fa6bbf4d85b9 (patch)
tree47dfb2453743e78b671584e08d9abe3af9e9d259
parent6bc91f23a6e14d540ab6950b438d40cf678143f0 (diff)
downloadgit-bc437d10202c015a5733f706dc44fa6bbf4d85b9.zip
git-bc437d10202c015a5733f706dc44fa6bbf4d85b9.tar.gz
git-bc437d10202c015a5733f706dc44fa6bbf4d85b9.tar.bz2
fetch: reduce duplicate in ref update status lines with placeholder
In the "remote -> local" line, if either ref is a substring of the other, the common part in the other string is replaced with "*". For example abc -> origin/abc refs/pull/123/head -> pull/123 become abc -> origin/* refs/*/head -> pull/123 Activated with fetch.output=compact. For the record, this output is not perfect. A single giant ref can push all refs very far to the right and likely be wrapped around. We may have a few options: - exclude these long lines smarter - break the line after "->", exclude it from column width calculation - implement a new format, { -> origin/}foo, which makes the problem go away at the cost of a bit harder to read - reverse all the arrows so we have "* <- looong-ref", again still hard to read. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--Documentation/config.txt5
-rw-r--r--Documentation/git-fetch.txt5
-rw-r--r--builtin/fetch.c77
-rwxr-xr-xt/t5510-fetch.sh17
4 files changed, 102 insertions, 2 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 2e1b2e4..7f6e58d 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1220,6 +1220,11 @@ fetch.prune::
If true, fetch will automatically behave as if the `--prune`
option was given on the command line. See also `remote.<name>.prune`.
+fetch.output::
+ Control how ref update status is printed. Valid values are
+ `full` and `compact`. Default value is `full`. See section
+ OUTPUT in linkgit:git-fetch[1] for detail.
+
format.attach::
Enable multipart/mixed attachments as the default for
'format-patch'. The value can also be a double quoted string
diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index 771dde5..9e42169 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -116,6 +116,11 @@ representing the status of a single ref. Each line is of the form:
The status of up-to-date refs is shown only if the --verbose option is
used.
+In compact output mode, specified with configuration variable
+fetch.output, if either entire `<from>` or `<to>` is found in the
+other string, it will be substituted with `*` in the other string. For
+example, `master -> origin/master` becomes `master -> origin/*`.
+
flag::
A single character indicating the status of the ref:
(space);; for a successfully fetched fast-forward;
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 2bc609b..0a2eed1 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -451,6 +451,7 @@ fail:
}
static int refcol_width = 10;
+static int compact_format;
static void adjust_refcol_width(const struct ref *ref)
{
@@ -462,6 +463,7 @@ static void adjust_refcol_width(const struct ref *ref)
max = term_columns();
rlen = utf8_strwidth(prettify_refname(ref->name));
+
llen = utf8_strwidth(prettify_refname(ref->peer_ref->name));
/*
@@ -470,10 +472,19 @@ static void adjust_refcol_width(const struct ref *ref)
* anyway because we don't know if the error explanation part
* will be printed in update_local_ref)
*/
+ if (compact_format) {
+ llen = 0;
+ max = max * 2 / 3;
+ }
len = 21 /* flag and summary */ + rlen + 4 /* -> */ + llen;
if (len >= max)
return;
+ /*
+ * Not precise calculation for compact mode because '*' can
+ * appear on the left hand side of '->' and shrink the column
+ * back.
+ */
if (refcol_width < rlen)
refcol_width = rlen;
}
@@ -481,6 +492,16 @@ static void adjust_refcol_width(const struct ref *ref)
static void prepare_format_display(struct ref *ref_map)
{
struct ref *rm;
+ const char *format = "full";
+
+ git_config_get_string_const("fetch.output", &format);
+ if (!strcasecmp(format, "full"))
+ compact_format = 0;
+ else if (!strcasecmp(format, "compact"))
+ compact_format = 1;
+ else
+ die(_("configuration fetch.output contains invalid value %s"),
+ format);
for (rm = ref_map; rm; rm = rm->next) {
if (rm->status == REF_STATUS_REJECT_SHALLOW ||
@@ -492,12 +513,66 @@ static void prepare_format_display(struct ref *ref_map)
}
}
+static void print_remote_to_local(struct strbuf *display,
+ const char *remote, const char *local)
+{
+ strbuf_addf(display, "%-*s -> %s", refcol_width, remote, local);
+}
+
+static int find_and_replace(struct strbuf *haystack,
+ const char *needle,
+ const char *placeholder)
+{
+ const char *p = strstr(haystack->buf, needle);
+ int plen, nlen;
+
+ if (!p)
+ return 0;
+
+ if (p > haystack->buf && p[-1] != '/')
+ return 0;
+
+ plen = strlen(p);
+ nlen = strlen(needle);
+ if (plen > nlen && p[nlen] != '/')
+ return 0;
+
+ strbuf_splice(haystack, p - haystack->buf, nlen,
+ placeholder, strlen(placeholder));
+ return 1;
+}
+
+static void print_compact(struct strbuf *display,
+ const char *remote, const char *local)
+{
+ struct strbuf r = STRBUF_INIT;
+ struct strbuf l = STRBUF_INIT;
+
+ if (!strcmp(remote, local)) {
+ strbuf_addf(display, "%-*s -> *", refcol_width, remote);
+ return;
+ }
+
+ strbuf_addstr(&r, remote);
+ strbuf_addstr(&l, local);
+
+ if (!find_and_replace(&r, local, "*"))
+ find_and_replace(&l, remote, "*");
+ print_remote_to_local(display, r.buf, l.buf);
+
+ strbuf_release(&r);
+ strbuf_release(&l);
+}
+
static void format_display(struct strbuf *display, char code,
const char *summary, const char *error,
const char *remote, const char *local)
{
strbuf_addf(display, "%c %-*s ", code, TRANSPORT_SUMMARY(summary));
- strbuf_addf(display, "%-*s -> %s", refcol_width, remote, local);
+ if (!compact_format)
+ print_remote_to_local(display, remote, local);
+ else
+ print_compact(display, remote, local);
if (error)
strbuf_addf(display, " (%s)", error);
}
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index f50497e..6032776 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -693,7 +693,7 @@ test_expect_success 'fetch aligned output' '
test_commit looooooooooooong-tag &&
(
cd full-output &&
- git fetch origin 2>&1 | \
+ git -c fetch.output=full fetch origin 2>&1 | \
grep -e "->" | cut -c 22- >../actual
) &&
cat >expect <<-\EOF &&
@@ -703,4 +703,19 @@ test_expect_success 'fetch aligned output' '
test_cmp expect actual
'
+test_expect_success 'fetch compact output' '
+ git clone . compact &&
+ test_commit extraaa &&
+ (
+ cd compact &&
+ git -c fetch.output=compact fetch origin 2>&1 | \
+ grep -e "->" | cut -c 22- >../actual
+ ) &&
+ cat >expect <<-\EOF &&
+ master -> origin/*
+ extraaa -> *
+ EOF
+ test_cmp expect actual
+'
+
test_done