From: Johan Herland <johan@herland.net>
To: git@vger.kernel.org
Cc: johan@herland.net, gitster@pobox.com, jrnieder@gmail.com
Subject: [PATCHv2 10/10] branch: Fix display of remote branches in refs/peers/*
Date: Sat, 11 May 2013 18:21:20 +0200 [thread overview]
Message-ID: <1368289280-30337-11-git-send-email-johan@herland.net> (raw)
In-Reply-To: <1368289280-30337-1-git-send-email-johan@herland.net>
The current branch display code assumes all remote-tracking branches live
inside refs/remotes/*, and that their appropriate shorthand names can be
retrieved by simply stripping off the "refs/remotes/" prefix.
When we add remote-tracking branches in refs/peers/$remote/heads/*, the
code must not only be taught how to list refs from the new location, but
also how to appropriately derive shorthand names for the remote-tracking
branches there (instead of stripping off a hardcoded prefix, we must use
the refname_shorten() function introduced in an earlier patch.)
There is already a good set of tests for the expected output from git
branch, and this patch does not break any of them. However, we do fix
the two tests with remote-tracking branches in refs/peers/* introduced
in a previous patch.
Signed-off-by: Johan Herland <johan@herland.net>
---
builtin/branch.c | 66 ++++++++++++++------------
refs.c | 4 +-
refs.h | 3 ++
t/t7900-working-with-namespaced-remote-refs.sh | 4 +-
4 files changed, 42 insertions(+), 35 deletions(-)
diff --git a/builtin/branch.c b/builtin/branch.c
index 4480be2..9a6bce8 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -290,18 +290,16 @@ struct ref_list {
int kinds;
};
-static char *resolve_symref(const char *src, const char *prefix)
+static void resolve_symref(struct strbuf *shortname, const char *pattern, const char *src)
{
unsigned char sha1[20];
int flag;
- const char *dst, *cp;
+ const char *dst;
dst = resolve_ref_unsafe(src, sha1, 0, &flag);
- if (!(dst && (flag & REF_ISSYMREF)))
- return NULL;
- if (prefix && (cp = skip_prefix(dst, prefix)))
- dst = cp;
- return xstrdup(dst);
+ if (dst && (flag & REF_ISSYMREF) &&
+ refname_shorten(shortname, pattern, dst, strlen(dst)))
+ strbuf_addstr(shortname, dst);
}
struct append_ref_cb {
@@ -328,74 +326,80 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
struct ref_list *ref_list = cb->ref_list;
struct ref_item *newitem;
struct commit *commit;
+ struct strbuf ref = STRBUF_INIT;
int kind, i;
- const char *prefix, *orig_refname = refname;
+ const char *pattern;
+ size_t refname_len = strlen(refname);
static struct {
int kind;
- const char *prefix;
- int pfxlen;
+ const char *pattern;
} ref_kind[] = {
- { REF_LOCAL_BRANCH, "refs/heads/", 11 },
- { REF_REMOTE_BRANCH, "refs/remotes/", 13 },
+ { REF_LOCAL_BRANCH, "refs/heads/%*" },
+ { REF_REMOTE_BRANCH, "refs/remotes/%*" },
+ { REF_REMOTE_BRANCH, "refs/peers/%1/heads/%*" },
};
/* Detect kind */
for (i = 0; i < ARRAY_SIZE(ref_kind); i++) {
- prefix = ref_kind[i].prefix;
- if (strncmp(refname, prefix, ref_kind[i].pfxlen))
+ if (refname_shorten(&ref, ref_kind[i].pattern, refname, refname_len))
continue;
kind = ref_kind[i].kind;
- refname += ref_kind[i].pfxlen;
+ pattern = ref_kind[i].pattern;
break;
}
if (ARRAY_SIZE(ref_kind) <= i)
- return 0;
+ goto out;
/* Don't add types the caller doesn't want */
if ((kind & ref_list->kinds) == 0)
- return 0;
+ goto out;
- if (!match_patterns(cb->pattern, refname))
- return 0;
+ if (!match_patterns(cb->pattern, ref.buf))
+ goto out;
commit = NULL;
if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
commit = lookup_commit_reference_gently(sha1, 1);
if (!commit) {
- cb->ret = error(_("branch '%s' does not point at a commit"), refname);
- return 0;
+ cb->ret = error(_("branch '%s' does not point at a commit"), ref.buf);
+ goto out;
}
/* Filter with with_commit if specified */
if (!is_descendant_of(commit, ref_list->with_commit))
- return 0;
+ goto out;
if (merge_filter != NO_FILTER)
add_pending_object(&ref_list->revs,
- (struct object *)commit, refname);
+ (struct object *)commit, ref.buf);
}
+ /*
+ * When displaying more then just remote-tracking branches, make the
+ * remote-tracking branches more explicit, e.g. instead of printing
+ * "origin/master", we should print "remote/origin/master" (or
+ * "peers/origin/heads/master").
+ */
+ if (kind == REF_REMOTE_BRANCH && ref_list->kinds != REF_REMOTE_BRANCH)
+ refname_shorten(&ref, "refs/%*", refname, refname_len);
+
ALLOC_GROW(ref_list->list, ref_list->index + 1, ref_list->alloc);
/* Record the new item */
newitem = &(ref_list->list[ref_list->index++]);
strbuf_init(&newitem->name, 0);
- strbuf_addstr(&newitem->name, refname);
+ strbuf_addbuf(&newitem->name, &ref);
newitem->kind = kind;
newitem->commit = commit;
strbuf_init(&newitem->dest, 0);
- orig_refname = resolve_symref(orig_refname, prefix);
- if (orig_refname)
- strbuf_addstr(&newitem->dest, orig_refname);
- /* adjust for "remotes/" */
- if (newitem->kind == REF_REMOTE_BRANCH &&
- ref_list->kinds != REF_REMOTE_BRANCH)
- strbuf_insert(&newitem->name, 0, "remotes/", 8);
+ resolve_symref(&newitem->dest, pattern, refname);
newitem->width = utf8_strwidth(newitem->name.buf);
if (newitem->width > ref_list->maxwidth)
ref_list->maxwidth = newitem->width;
+out:
+ strbuf_release(&ref);
return 0;
}
diff --git a/refs.c b/refs.c
index 188a9eb..a78199a 100644
--- a/refs.c
+++ b/refs.c
@@ -1873,8 +1873,8 @@ static int handle_fragment(struct strbuf *dst, struct strbuf *fragment,
return (ref - refname) + trail_len;
}
-static int refname_shorten(struct strbuf *dst, const char *pattern,
- const char *refname, size_t refname_len)
+int refname_shorten(struct strbuf *dst, const char *pattern,
+ const char *refname, size_t refname_len)
{
/*
* Match refname against pattern, using "%*" as wildcard, and
diff --git a/refs.h b/refs.h
index e05c1f1..245d53d 100644
--- a/refs.h
+++ b/refs.h
@@ -165,6 +165,9 @@ extern int check_refname_format(const char *refname, int flags);
extern const char *prettify_refname(const char *refname);
+extern int refname_shorten(struct strbuf *dst, const char *pattern,
+ const char *refname, size_t refname_len);
+
extern int refname_match(const char *abbrev_name, const char *full_name);
extern char *shorten_unambiguous_ref(const char *refname, int strict);
diff --git a/t/t7900-working-with-namespaced-remote-refs.sh b/t/t7900-working-with-namespaced-remote-refs.sh
index 279664c..450b193 100755
--- a/t/t7900-working-with-namespaced-remote-refs.sh
+++ b/t/t7900-working-with-namespaced-remote-refs.sh
@@ -112,7 +112,7 @@ cat >expect.branch-r << EOF
origin/other
EOF
-test_expect_failure 'git branch -r should show remote-tracking branches' '
+test_expect_success 'git branch -r should show remote-tracking branches' '
git branch -r >actual.branch-r &&
test_cmp expect.branch-r actual.branch-r
'
@@ -123,7 +123,7 @@ cat >expect.branch-a << EOF
peers/origin/heads/other
EOF
-test_expect_failure 'git branch -a should also show remote-tracking branches' '
+test_expect_success 'git branch -a should also show remote-tracking branches' '
git branch -a >actual.branch-a &&
test_cmp expect.branch-a actual.branch-a
'
--
1.8.1.3.704.g33f7d4f
next prev parent reply other threads:[~2013-05-11 16:21 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-11 16:21 [PATCHv2 00/10] Prepare for alternative remote-tracking branch location Johan Herland
2013-05-11 16:21 ` [PATCHv2 01/10] t7900: Start testing usability of namespaced remote refs Johan Herland
2013-05-11 16:21 ` [PATCHv2 02/10] t7900: Demonstrate failure to expand "$peer/$branch" according to refspecs Johan Herland
2013-05-11 16:21 ` [PATCHv2 03/10] refs.c: Refactor code for mapping between shorthand names and full refnames Johan Herland
2013-05-13 4:56 ` Junio C Hamano
2013-05-13 6:31 ` Johan Herland
2013-05-13 6:45 ` Junio C Hamano
2013-05-13 20:34 ` Junio C Hamano
2013-05-14 14:24 ` Johan Herland
2013-05-14 17:50 ` Junio C Hamano
2013-05-15 6:45 ` Michael Haggerty
2013-05-15 7:39 ` Johan Herland
2013-05-15 13:53 ` Johan Herland
2013-05-15 15:14 ` Junio C Hamano
2013-05-15 19:49 ` Eric Wong
2013-05-11 16:21 ` [PATCHv2 04/10] remote: Reject remote names containing '/' Johan Herland
2013-05-13 4:48 ` Eric Sunshine
2013-05-13 6:32 ` Johan Herland
2013-05-13 4:54 ` Junio C Hamano
2013-05-13 6:53 ` Johan Herland
2013-05-16 9:48 ` Ramkumar Ramachandra
2013-05-16 11:17 ` Johan Herland
2013-05-16 12:14 ` Ramkumar Ramachandra
2013-05-11 16:21 ` [PATCHv2 05/10] refs.c: Add support for expanding/shortening refs in refs/peers/* Johan Herland
2013-05-11 16:21 ` [PATCHv2 06/10] t7900: Test git branch -r/-a output w/remote-tracking branches " Johan Herland
2013-05-11 16:21 ` [PATCHv2 07/10] t3203: Add testcase for fix in 1603ade81352a526ccb206f41ff81ecbc855df2d Johan Herland
2013-05-11 16:21 ` [PATCHv2 08/10] builtin/branch.c: Refactor ref_item.name and .dest into strbufs Johan Herland
2013-05-11 16:21 ` [PATCHv2 09/10] builtin/branch.c: Refactor "remotes/" prepending to remote-tracking branches Johan Herland
2013-05-11 16:21 ` Johan Herland [this message]
2013-05-13 5:19 ` [PATCHv2 10/10] branch: Fix display of remote branches in refs/peers/* Eric Sunshine
2013-05-13 6:55 ` Johan Herland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1368289280-30337-11-git-send-email-johan@herland.net \
--to=johan@herland.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jrnieder@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).