[PATCH 4/5] interpret_branch_name: takes @{u} code out and reorder the function
Previously interpret_branch_name() is structured as:
- check for @{-N}
- if there's still some more chars left, recurse to try again
- check for @{upstream}Now it looks like
- check for @{-N}
- check for @{upstream}
- still more? recurseSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
sha1_name.c | 99 ++++++++++++++++++++++++++++++++++-------------------------
1 files changed, 57 insertions(+), 42 deletions(-)
diff --git a/sha1_name.c b/sha1_name.c
index dcdf1e6..cdf14c7 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -973,6 +973,27 @@ release_return:
return retval;
}
+static int interpret_at_upstream(const char *at, struct strbuf *real_ref)
+{
+ struct branch *upstream;
+ int cplen = strlen(at);
+ int len;
+ char *upstream_ref;
+
+ len = upstream_mark(at, cplen);
+ if (!len)
+ return -1;
+ upstream = branch_get(real_ref->buf);
+ if (!upstream
+ || !upstream->merge
+ || !upstream->merge[0]->dst)
+ return error("No upstream branch found for '%s'", real_ref->buf);
+ upstream_ref = shorten_unambiguous_ref(upstream->merge[0]->dst, 0);
+ cplen = strlen(upstream_ref);
+ strbuf_attach(real_ref, upstream_ref, cplen, cplen+1);
+ return len;
+}
+
/*
* 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
@@ -996,55 +1017,49 @@ release_return:
*/
int interpret_branch_name(const char *name, struct strbuf *buf)
{
- char *cp;
- struct branch *upstream;
int namelen = strlen(name);
- int len = interpret_nth_prior_checkout(name, buf);
- int tmp_len;
-
- if (!len)
- return len; /* syntax Ok, not enough switches */
- if (0 < len && len == namelen)
- return len; /* consumed all */
- else if (0 < len) {
- /* we have extra data, which might need further processing */
- struct strbuf tmp = STRBUF_INIT;
- int used = buf->len;
- int ret;
-
- strbuf_add(buf, name + len, namelen - len);
- ret = interpret_branch_name(buf->buf, &tmp);
- /* that data was not interpreted, remove our cruft */
- if (ret < 0) {
- strbuf_setlen(buf, used);
- return len;
- }
- strbuf_reset(buf);
- strbuf_addbuf(buf, &tmp);
- strbuf_release(&tmp);
- /* tweak for size of {-N} versus expanded ref name */
- return ret - used + len;
- }
+ struct strbuf tmp = STRBUF_INIT;
+ int ret, len = -1, used = 0;
+ const char *cp;
cp = strchr(name, '@');
if (!cp)
return -1;
- tmp_len = upstream_mark(cp, namelen - (cp - name));
- if (!tmp_len)
+ if (cp == name)
+ len = interpret_nth_prior_checkout(cp, buf);
+ else {
+ strbuf_reset(buf);
+ strbuf_add(buf, name, cp - name);
+ used += cp - name;
+ }
+
+ if (len == -1)
+ len = interpret_at_upstream(cp, buf);
+ if (len == -1) {
+ strbuf_reset(buf);
return -1;
- len = cp + tmp_len - name;
- cp = xstrndup(name, cp - name);
- upstream = branch_get(*cp ? cp : NULL);
- if (!upstream
- || !upstream->merge
- || !upstream->merge[0]->dst)
- return error("No upstream branch found for '%s'", cp);
- free(cp);
- cp = shorten_unambiguous_ref(upstream->merge[0]->dst, 0);
+ }
+
+ if (!len)
+ return len; /* syntax Ok, not enough switches */
+
+ used += len;
+ if (used == namelen)
+ return used; /* consumed all */
+
+ /* we have extra data, which might need further processing */
+ len = buf->len;
+ strbuf_add(buf, name + used, namelen - used);
+ ret = interpret_branch_name(buf->buf, &tmp);
+ /* that data was not interpreted, remove our cruft */
+ if (ret < 0) {
+ strbuf_setlen(buf, len);
+ return used;
+ }
strbuf_reset(buf);
- strbuf_addstr(buf, cp);
- free(cp);
- return len;
+ strbuf_addbuf(buf, &tmp);
+ strbuf_release(&tmp);
+ return used + (ret - len);
}
int strbuf_branchname(struct strbuf *sb, const char *name)
--
1.7.3.3.476.g10a82