From 3a429d0af342d85ef6d561e3a60ae8793a34ae78 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 21 May 2015 00:45:32 -0400 Subject: remote.c: report specific errors from branch_get_upstream When the previous commit introduced the branch_get_upstream helper, there was one call-site that could not be converted: the one in sha1_name.c, which gives detailed error messages for each possible failure. Let's teach the helper to optionally report these specific errors. This lets us convert another callsite, and means we can use the helper in other locations that want to give the same error messages. The logic and error messages come straight from sha1_name.c, with the exception that we start each error with a lowercase letter, as is our usual style (note that a few tests need updated as a result). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- sha1_name.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'sha1_name.c') diff --git a/sha1_name.c b/sha1_name.c index 6d10f052b5..461157a5bc 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -1059,27 +1059,16 @@ 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); + struct strbuf err = STRBUF_INIT; + const char *ret; - /* - * 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; + ret = branch_get_upstream(upstream, &err); + if (!ret) + die("%s", err.buf); + + return ret; } static int interpret_upstream_mark(const char *name, int namelen, -- cgit v1.2.3 From a1ad0eb0cb1c9c83492b17d7a218be084466bf9a Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 21 May 2015 00:45:39 -0400 Subject: sha1_name: refactor upstream_mark We will be adding new mark types in the future, so separate the suffix data from the logic. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- sha1_name.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'sha1_name.c') diff --git a/sha1_name.c b/sha1_name.c index 461157a5bc..1005f45d75 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -415,12 +415,12 @@ static int ambiguous_path(const char *path, int len) return slash; } -static inline int upstream_mark(const char *string, int len) +static inline int at_mark(const char *string, int len, + const char **suffix, int nr) { - const char *suffix[] = { "@{upstream}", "@{u}" }; int i; - for (i = 0; i < ARRAY_SIZE(suffix); i++) { + for (i = 0; i < nr; i++) { int suffix_len = strlen(suffix[i]); if (suffix_len <= len && !memcmp(string, suffix[i], suffix_len)) @@ -429,6 +429,12 @@ static inline int upstream_mark(const char *string, int len) return 0; } +static inline int upstream_mark(const char *string, int len) +{ + const char *suffix[] = { "@{upstream}", "@{u}" }; + return at_mark(string, len, suffix, ARRAY_SIZE(suffix)); +} + static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned lookup_flags); static int interpret_nth_prior_checkout(const char *name, int namelen, struct strbuf *buf); -- cgit v1.2.3 From 48c58471c2d4d7293272448a18801cd27555f6b5 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 21 May 2015 00:45:43 -0400 Subject: sha1_name: refactor interpret_upstream_mark Now that most of the logic for our local get_upstream_branch has been pushed into the generic branch_get_upstream, we can fold the remainder into interpret_upstream_mark. Furthermore, what remains is generic to any branch-related "@{foo}" we might add in the future, and there's enough boilerplate that we'd like to reuse it. Let's parameterize the two operations (parsing the mark and computing its value) so that we can reuse this for "@{push}" in the near future. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- sha1_name.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'sha1_name.c') diff --git a/sha1_name.c b/sha1_name.c index 1005f45d75..506e0c92ee 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -1061,35 +1061,36 @@ static void set_shortened_ref(struct strbuf *buf, const char *ref) 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); - struct strbuf err = STRBUF_INIT; - const char *ret; - - free(branch); - - ret = branch_get_upstream(upstream, &err); - if (!ret) - die("%s", err.buf); - - return ret; -} - -static int interpret_upstream_mark(const char *name, int namelen, - int at, struct strbuf *buf) +static int interpret_branch_mark(const char *name, int namelen, + int at, struct strbuf *buf, + int (*get_mark)(const char *, int), + const char *(*get_data)(struct branch *, + struct strbuf *)) { int len; + struct branch *branch; + struct strbuf err = STRBUF_INIT; + const char *value; - len = upstream_mark(name + at, namelen - at); + len = get_mark(name + at, namelen - at); if (!len) return -1; if (memchr(name, ':', at)) return -1; - set_shortened_ref(buf, get_upstream_branch(name, at)); + if (at) { + char *name_str = xmemdupz(name, at); + branch = branch_get(name_str); + free(name_str); + } else + branch = branch_get(NULL); + + value = get_data(branch, &err); + if (!value) + die("%s", err.buf); + + set_shortened_ref(buf, value); return len + at; } @@ -1140,7 +1141,8 @@ int interpret_branch_name(const char *name, int namelen, struct strbuf *buf) if (len > 0) return reinterpret(name, namelen, len, buf); - len = interpret_upstream_mark(name, namelen, at - name, buf); + len = interpret_branch_mark(name, namelen, at - name, buf, + upstream_mark, branch_get_upstream); if (len > 0) return len; } -- cgit v1.2.3 From adfe5d04345631299f9a4518d56c6dd3d47eb0b3 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 21 May 2015 00:45:47 -0400 Subject: sha1_name: implement @{push} shorthand In a triangular workflow, each branch may have two distinct points of interest: the @{upstream} that you normally pull from, and the destination that you normally push to. There isn't a shorthand for the latter, but it's useful to have. For instance, you may want to know which commits you haven't pushed yet: git log @{push}.. Or as a more complicated example, imagine that you normally pull changes from origin/master (which you set as your @{upstream}), and push changes to your own personal fork (e.g., as myfork/topic). You may push to your fork from multiple machines, requiring you to integrate the changes from the push destination, rather than upstream. With this patch, you can just do: git rebase @{push} rather than typing out the full name. The heavy lifting is all done by branch_get_push; here we just wire it up to the "@{push}" syntax. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- sha1_name.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'sha1_name.c') diff --git a/sha1_name.c b/sha1_name.c index 506e0c92ee..10969435bb 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -435,6 +435,12 @@ static inline int upstream_mark(const char *string, int len) return at_mark(string, len, suffix, ARRAY_SIZE(suffix)); } +static inline int push_mark(const char *string, int len) +{ + const char *suffix[] = { "@{push}" }; + return at_mark(string, len, suffix, ARRAY_SIZE(suffix)); +} + static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned lookup_flags); static int interpret_nth_prior_checkout(const char *name, int namelen, struct strbuf *buf); @@ -482,7 +488,8 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1, nth_prior = 1; continue; } - if (!upstream_mark(str + at, len - at)) { + if (!upstream_mark(str + at, len - at) && + !push_mark(str + at, len - at)) { reflog_len = (len-1) - (at+2); len = at; } @@ -1145,6 +1152,11 @@ int interpret_branch_name(const char *name, int namelen, struct strbuf *buf) upstream_mark, branch_get_upstream); if (len > 0) return len; + + len = interpret_branch_mark(name, namelen, at - name, buf, + push_mark, branch_get_push); + if (len > 0) + return len; } return -1; -- cgit v1.2.3