remote.c: untangle error logic in branch_get_upstream
authorJeff King <peff@peff.net>
Fri, 22 May 2015 00:46:43 +0000 (20:46 -0400)
committerJunio C Hamano <gitster@pobox.com>
Fri, 22 May 2015 16:30:51 +0000 (09:30 -0700)
The error-diagnosis logic in branch_get_upstream was copied
straight from sha1_name.c in the previous commit. However,
because we check all error cases and upfront and then later
diagnose them, the logic is a bit tangled. In particular:

- if branch->merge[0] is NULL, we may end up dereferencing
it for an error message (in practice, it should never be
NULL, so this is probably not a triggerable bug).

- We may enter the code path because branch->merge[0]->dst
is NULL, but we then start our error diagnosis by
checking whether our local branch exists. But that is
only relevant to diagnosing missing merge config, not a
missing tracking ref; our diagnosis may hide the real
problem.

Instead, let's just use a sequence of "if" blocks to check
for each error type, diagnose it, and return NULL.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
remote.c
index 1b7051a18722700907f969e6c88f355b91f5ec3b..d2519c22ce85921ae5c231b099ac0735bb09814e 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -1721,18 +1721,25 @@ const char *branch_get_upstream(struct branch *branch, struct strbuf *err)
 {
        if (!branch)
                return error_buf(err, _("HEAD does not point to a branch"));
-       if (!branch->merge || !branch->merge[0] || !branch->merge[0]->dst) {
+
+       if (!branch->merge || !branch->merge[0]) {
+               /*
+                * no merge config; is it because the user didn't define any,
+                * or because it is not a real branch, and get_branch
+                * auto-vivified it?
+                */
                if (!ref_exists(branch->refname))
                        return error_buf(err, _("no such branch: '%s'"),
                                         branch->name);
-               if (!branch->merge)
-                       return error_buf(err,
-                                        _("no upstream configured for branch '%s'"),
-                                        branch->name);
+               return error_buf(err,
+                                _("no upstream configured for branch '%s'"),
+                                branch->name);
+       }
+
+       if (!branch->merge[0]->dst)
                return error_buf(err,
                                 _("upstream branch '%s' not stored as a remote-tracking branch"),
                                 branch->merge[0]->src);
-       }
 
        return branch->merge[0]->dst;
 }