interpret_branch_name: factor out upstream handling

This function checks a few different @{}-constructs. The
early part checks for and dispatches us to helpers for each
construct, but the code for handling @{upstream} is inline.

Let's factor this out into its own function. This makes
interpret_branch_name more readable, and will make it much
simpler to further refactor the function in future patches.

While we're at it, let's also break apart the refactored
code into a few helper functions. These will be useful if we
eventually implement similar @{upstream}-like constructs.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2014-01-15 03:26:33 -05:00 committed by Junio C Hamano
parent 4224916ae9
commit a39c14af82

View file

@ -1048,6 +1048,54 @@ static int reinterpret(const char *name, int namelen, int len, struct strbuf *bu
return ret - used + len;
}
static void set_shortened_ref(struct strbuf *buf, const char *ref)
{
char *s = shorten_unambiguous_ref(ref, 0);
strbuf_reset(buf);
strbuf_addstr(buf, s);
free(s);
}
static const char *get_upstream_branch(const char *branch_buf, int len)
{
char *branch = xstrndup(branch_buf, len);
struct branch *upstream = branch_get(*branch ? branch : NULL);
/*
* Upstream can be NULL only if branch refers to HEAD and HEAD
* points to something different than a branch.
*/
if (!upstream)
die(_("HEAD does not point to a branch"));
if (!upstream->merge || !upstream->merge[0]->dst) {
if (!ref_exists(upstream->refname))
die(_("No such branch: '%s'"), branch);
if (!upstream->merge) {
die(_("No upstream configured for branch '%s'"),
upstream->name);
}
die(
_("Upstream branch '%s' not stored as a remote-tracking branch"),
upstream->merge[0]->src);
}
free(branch);
return upstream->merge[0]->dst;
}
static int interpret_upstream_mark(const char *name, int namelen,
int at, struct strbuf *buf)
{
int len;
len = upstream_mark(name + at, namelen - at);
if (!len)
return -1;
set_shortened_ref(buf, get_upstream_branch(name, at));
return len + at;
}
/*
* This reads short-hand syntax that not only evaluates to a commit
* object name, but also can act as if the end user spelled the name
@ -1072,9 +1120,7 @@ static int reinterpret(const char *name, int namelen, int len, struct strbuf *bu
int interpret_branch_name(const char *name, int namelen, struct strbuf *buf)
{
char *cp;
struct branch *upstream;
int len = interpret_nth_prior_checkout(name, buf);
int tmp_len;
if (!namelen)
namelen = strlen(name);
@ -1096,36 +1142,11 @@ int interpret_branch_name(const char *name, int namelen, struct strbuf *buf)
if (len > 0)
return reinterpret(name, namelen, len, buf);
tmp_len = upstream_mark(cp, namelen - (cp - name));
if (!tmp_len)
return -1;
len = interpret_upstream_mark(name, namelen, cp - name, buf);
if (len > 0)
return len;
len = cp + tmp_len - name;
cp = xstrndup(name, cp - name);
upstream = branch_get(*cp ? cp : NULL);
/*
* Upstream can be NULL only if cp refers to HEAD and HEAD
* points to something different than a branch.
*/
if (!upstream)
die(_("HEAD does not point to a branch"));
if (!upstream->merge || !upstream->merge[0]->dst) {
if (!ref_exists(upstream->refname))
die(_("No such branch: '%s'"), cp);
if (!upstream->merge) {
die(_("No upstream configured for branch '%s'"),
upstream->name);
}
die(
_("Upstream branch '%s' not stored as a remote-tracking branch"),
upstream->merge[0]->src);
}
free(cp);
cp = shorten_unambiguous_ref(upstream->merge[0]->dst, 0);
strbuf_reset(buf);
strbuf_addstr(buf, cp);
free(cp);
return len;
return -1;
}
int strbuf_branchname(struct strbuf *sb, const char *name)