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 <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed May 21, 2015 at 00:45 UTC 3a429d0af342d85ef6d561e3a60ae8793a34ae78
7 files changed +48 -30
builtin/branch.c
+1 -1
@@ -123,7 +123,7 @@ static int branch_merged(int kind, const char *name,
123
124 if (kind == REF_LOCAL_BRANCH) {
125 struct branch *branch = branch_get(name);
126 - const char *upstream = branch_get_upstream(branch);
126 + const char *upstream = branch_get_upstream(branch, NULL);
127 unsigned char sha1[20];
128
129 if (upstream &&
builtin/for-each-ref.c
+1 -1
@@ -664,7 +664,7 @@ static void populate_value(struct refinfo *ref)
664 continue;
665 branch = branch_get(ref->refname + 11);
666
667 - refname = branch_get_upstream(branch);
667 + refname = branch_get_upstream(branch, NULL);
668 if (!refname)
669 continue;
670 } else if (starts_with(name, "color:")) {
builtin/log.c
+1 -1
@@ -1632,7 +1632,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
1632 break;
1633 default:
1634 current_branch = branch_get(NULL);
1635 - upstream = branch_get_upstream(current_branch);
1635 + upstream = branch_get_upstream(current_branch, NULL);
1636 if (!upstream) {
1637 fprintf(stderr, _("Could not find a tracked"
1638 " remote branch, please"
remote.c
+29 -4
@@ -1705,10 +1705,35 @@ int branch_merge_matches(struct branch *branch,
1705 return refname_match(branch->merge[i]->src, refname);
1706 }
1707
1708 -const char *branch_get_upstream(struct branch *branch)
1708 +__attribute((format (printf,2,3)))
1709 +static const char *error_buf(struct strbuf *err, const char *fmt, ...)
1710 {
1710 - if (!branch || !branch->merge || !branch->merge[0])
1711 - return NULL;
1711 + if (err) {
1712 + va_list ap;
1713 + va_start(ap, fmt);
1714 + strbuf_vaddf(err, fmt, ap);
1715 + va_end(ap);
1716 + }
1717 + return NULL;
1718 +}
1719 +
1720 +const char *branch_get_upstream(struct branch *branch, struct strbuf *err)
1721 +{
1722 + if (!branch)
1723 + return error_buf(err, _("HEAD does not point to a branch"));
1724 + if (!branch->merge || !branch->merge[0] || !branch->merge[0]->dst) {
1725 + if (!ref_exists(branch->refname))
1726 + return error_buf(err, _("no such branch: '%s'"),
1727 + branch->name);
1728 + if (!branch->merge)
1729 + return error_buf(err,
1730 + _("no upstream configured for branch '%s'"),
1731 + branch->name);
1732 + return error_buf(err,
1733 + _("upstream branch '%s' not stored as a remote-tracking branch"),
1734 + branch->merge[0]->src);
1735 + }
1736 +
1737 return branch->merge[0]->dst;
1738 }
1739
@@ -1921,7 +1946,7 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)
1946 int rev_argc;
1947
1948 /* Cannot stat unless we are marked to build on top of somebody else. */
1924 - base = branch_get_upstream(branch);
1949 + base = branch_get_upstream(branch, NULL);
1950 if (!base)
1951 return 0;
1952
remote.h
+5 -1
@@ -222,8 +222,12 @@ int branch_merge_matches(struct branch *, int n, const char *);
222 * Return the fully-qualified refname of the tracking branch for `branch`.
223 * I.e., what "branch@{upstream}" would give you. Returns NULL if no
224 * upstream is defined.
225 + *
226 + * If `err` is not NULL and no upstream is defined, a more specific error
227 + * message is recorded there (if the function does not return NULL, then
228 + * `err` is not touched).
229 */
226 -const char *branch_get_upstream(struct branch *branch);
230 +const char *branch_get_upstream(struct branch *branch, struct strbuf *err);
231
232 /* Flags to match_refs. */
233 enum match_refs_flags {
sha1_name.c
+7 -18
@@ -1059,27 +1059,16 @@ static const char *get_upstream_branch(const char *branch_buf, int len)
1059 {
1060 char *branch = xstrndup(branch_buf, len);
1061 struct branch *upstream = branch_get(*branch ? branch : NULL);
1062 + struct strbuf err = STRBUF_INIT;
1063 + const char *ret;
1064
1063 - /*
1064 - * Upstream can be NULL only if branch refers to HEAD and HEAD
1065 - * points to something different than a branch.
1066 - */
1067 - if (!upstream)
1068 - die(_("HEAD does not point to a branch"));
1069 - if (!upstream->merge || !upstream->merge[0]->dst) {
1070 - if (!ref_exists(upstream->refname))
1071 - die(_("No such branch: '%s'"), branch);
1072 - if (!upstream->merge) {
1073 - die(_("No upstream configured for branch '%s'"),
1074 - upstream->name);
1075 - }
1076 - die(
1077 - _("Upstream branch '%s' not stored as a remote-tracking branch"),
1078 - upstream->merge[0]->src);
1079 - }
1065 free(branch);
1066
1082 - return upstream->merge[0]->dst;
1067 + ret = branch_get_upstream(upstream, &err);
1068 + if (!ret)
1069 + die("%s", err.buf);
1070 +
1071 + return ret;
1072 }
1073
1074 static int interpret_upstream_mark(const char *name, int namelen,
t/t1507-rev-parse-upstream.sh
+4 -4
@@ -150,7 +150,7 @@ test_expect_success 'branch@{u} works when tracking a local branch' '
150
151 test_expect_success 'branch@{u} error message when no upstream' '
152 cat >expect <<-EOF &&
153 - fatal: No upstream configured for branch ${sq}non-tracking${sq}
153 + fatal: no upstream configured for branch ${sq}non-tracking${sq}
154 EOF
155 error_message non-tracking@{u} 2>actual &&
156 test_i18ncmp expect actual
@@ -158,7 +158,7 @@ test_expect_success 'branch@{u} error message when no upstream' '
158
159 test_expect_success '@{u} error message when no upstream' '
160 cat >expect <<-EOF &&
161 - fatal: No upstream configured for branch ${sq}master${sq}
161 + fatal: no upstream configured for branch ${sq}master${sq}
162 EOF
163 test_must_fail git rev-parse --verify @{u} 2>actual &&
164 test_i18ncmp expect actual
@@ -166,7 +166,7 @@ test_expect_success '@{u} error message when no upstream' '
166
167 test_expect_success 'branch@{u} error message with misspelt branch' '
168 cat >expect <<-EOF &&
169 - fatal: No such branch: ${sq}no-such-branch${sq}
169 + fatal: no such branch: ${sq}no-such-branch${sq}
170 EOF
171 error_message no-such-branch@{u} 2>actual &&
172 test_i18ncmp expect actual
@@ -183,7 +183,7 @@ test_expect_success '@{u} error message when not on a branch' '
183
184 test_expect_success 'branch@{u} error message if upstream branch not fetched' '
185 cat >expect <<-EOF &&
186 - fatal: Upstream branch ${sq}refs/heads/side${sq} not stored as a remote-tracking branch
186 + fatal: upstream branch ${sq}refs/heads/side${sq} not stored as a remote-tracking branch
187 EOF
188 error_message bad-upstream@{u} 2>actual &&
189 test_i18ncmp expect actual