branch: fix shortening of non-remote symrefs

Commit aedcb7d (branch.c: use 'ref-filter' APIs, 2015-09-23) adjusted the symref-printing code to look like this: if (item->symref) { skip_prefix(item->symref, "refs/remotes/", &desc); strbuf_addf(&out, " -> %s", desc); } This has three bugs in it: 1. It always skips past "refs/remotes/", instead of skipping past the prefix associated with the branch we are showing (so commonly we see "refs/remotes/" for the refs/remotes/origin/HEAD symref, but the previous code would skip "refs/heads/" when showing a symref it found in refs/heads/. 2. If skip_prefix() does not match, it leaves "desc" untouched, and we show whatever happened to be in it (which is the refname from a call to skip_prefix() earlier in the function). 3. If we do match with skip_prefix(), we stomp on the "desc" variable, which is later passed to add_verbose_info(). We probably want to retain the original refname there (though it likely doesn't matter in practice, since after all, one points to the other). The fix to match the original code is fairly easy: record the prefix to strip based on item->kind, and use it here. However, since we already have a local variable named "prefix", let's give the two prefixes verbose names so we don't confuse them. Signed-off-by: Jeff King <peff@peff.net> Acked-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Apr 3, 2016 at 00:14 UTC 95c38fb0ed45d9eb529afeb704b840818ba3da4d
2 files changed +24 -7
builtin/branch.c
+12 -7
@@ -393,22 +393,25 @@ static void format_and_print_ref_item(struct ref_array_item *item, int maxwidth,
393 int current = 0;
394 int color;
395 struct strbuf out = STRBUF_INIT, name = STRBUF_INIT;
396 - const char *prefix = "";
396 + const char *prefix_to_show = "";
397 + const char *prefix_to_skip = NULL;
398 const char *desc = item->refname;
399 char *to_free = NULL;
400
401 switch (item->kind) {
402 case FILTER_REFS_BRANCHES:
402 - skip_prefix(desc, "refs/heads/", &desc);
403 + prefix_to_skip = "refs/heads/";
404 + skip_prefix(desc, prefix_to_skip, &desc);
405 if (!filter->detached && !strcmp(desc, head))
406 current = 1;
407 else
408 color = BRANCH_COLOR_LOCAL;
409 break;
410 case FILTER_REFS_REMOTES:
409 - skip_prefix(desc, "refs/remotes/", &desc);
411 + prefix_to_skip = "refs/remotes/";
412 + skip_prefix(desc, prefix_to_skip, &desc);
413 color = BRANCH_COLOR_REMOTE;
411 - prefix = remote_prefix;
414 + prefix_to_show = remote_prefix;
415 break;
416 case FILTER_REFS_DETACHED_HEAD:
417 desc = to_free = get_head_description();
@@ -425,7 +428,7 @@ static void format_and_print_ref_item(struct ref_array_item *item, int maxwidth,
428 color = BRANCH_COLOR_CURRENT;
429 }
430
428 - strbuf_addf(&name, "%s%s", prefix, desc);
431 + strbuf_addf(&name, "%s%s", prefix_to_show, desc);
432 if (filter->verbose) {
433 int utf8_compensation = strlen(name.buf) - utf8_strwidth(name.buf);
434 strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(color),
@@ -436,8 +439,10 @@ static void format_and_print_ref_item(struct ref_array_item *item, int maxwidth,
439 name.buf, branch_get_color(BRANCH_COLOR_RESET));
440
441 if (item->symref) {
439 - skip_prefix(item->symref, "refs/remotes/", &desc);
440 - strbuf_addf(&out, " -> %s", desc);
442 + const char *symref = item->symref;
443 + if (prefix_to_skip)
444 + skip_prefix(symref, prefix_to_skip, &symref);
445 + strbuf_addf(&out, " -> %s", symref);
446 }
447 else if (filter->verbose)
448 /* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */
t/t3203-branch-output.sh
+12
@@ -184,4 +184,16 @@ test_expect_success 'ambiguous branch/tag not marked' '
184 test_cmp expect actual
185 '
186
187 +test_expect_success 'local-branch symrefs shortened properly' '
188 + git symbolic-ref refs/heads/ref-to-branch refs/heads/branch-one &&
189 + git symbolic-ref refs/heads/ref-to-remote refs/remotes/origin/branch-one &&
190 + cat >expect <<-\EOF &&
191 + ref-to-branch -> branch-one
192 + ref-to-remote -> refs/remotes/origin/branch-one
193 + EOF
194 + git branch >actual.raw &&
195 + grep ref-to <actual.raw >actual &&
196 + test_cmp expect actual
197 +'
198 +
199 test_done