git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v3 08/14] remote.c: report specific errors from branch_get_upstream

From
Jeff King <peff@peff.net>
Date
May 22, 2015, 00:46 UTC
Message-ID
<20150522004643.GA11739@peff.net>
In-Reply-To
<xmqqpp5tivga.fsf@gitster.dls.corp.google.com>
On Thu, May 21, 2015 at 12:25:57PM -0700, Junio C Hamano wrote:
Show 8 quoted lines
> > Note also that the original may dereference branch->merge[0] even if it
> > is NULL. I think that can't actually happen in practice (we only
> > allocate branch->merge if we have at least one item to put in it, and
> > all of the checks of branch->merge[0] are actually being over-careful).
> > But the code I just wrote above does not have that problem.
> 
> Perhaps update the patch with this explanation in the log message,
> as a separate preparatory step?

I decided on a separate patch on top which improves the logic and explains the issues. Here it is (it goes on top of the existing patch 8, "report specific errors from branch_get_upstream").

-- >8 --
Subject: remote.c: untangle error logic in branch_get_upstream

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>
---
 remote.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/remote.c b/remote.c
index 1b7051a..d2519c2 100644
--- 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;
 }
-- 
2.4.1.528.g00591e3
Previous: Junio C HamanoNext: Jeff King
Message 18 of 27 in “implement @{push} shorthand”
  1. 0/14 implement @{push} shorthandJeff King, May 21, 2015
  2. 01/14 remote.c: drop default_remote_name variableJeff King, May 21, 2015
  3. 02/14 remote.c: refactor setup of branch->merge listJeff King, May 21, 2015
  4. Junio C HamanoMay 21, 2015
  5. 03/14 remote.c: drop "remote" pointer from "struct branch"Jeff King, May 21, 2015
  6. 04/14 remote.c: hoist branch.*.remote lookup out of remote_get_1Jeff King, May 21, 2015
  7. 05/14 remote.c: provide per-branch pushremote nameJeff King, May 21, 2015
  8. 06/14 remote.c: hoist read_config into remote_get_1Jeff King, May 21, 2015
  9. 07/14 remote.c: introduce branch_get_upstream helperJeff King, May 21, 2015
  10. Junio C HamanoMay 21, 2015
  11. Jeff KingMay 21, 2015
  12. Jeff KingMay 21, 2015
  13. Junio C HamanoMay 21, 2015
  14. 08/14 remote.c: report specific errors from branch_get_upstreamJeff King, May 21, 2015
  15. Junio C HamanoMay 21, 2015
  16. Jeff KingMay 21, 2015
  17. Junio C HamanoMay 21, 2015
  18. Jeff KingMay 22, 2015
  19. Jeff KingMay 22, 2015
  20. 09/14 remote.c: add branch_get_pushJeff King, May 21, 2015
  21. 10/14 sha1_name: refactor upstream_markJeff King, May 21, 2015
  22. 11/14 sha1_name: refactor interpret_upstream_markJeff King, May 21, 2015
  23. 12/14 sha1_name: implement @{push} shorthandJeff King, May 21, 2015
  24. 13/14 for-each-ref: use skip_prefix instead of starts_withJeff King, May 21, 2015
  25. 14/14 for-each-ref: accept "%(push)" formatJeff King, May 21, 2015
  26. Jeff KingMay 21, 2015
  27. Junio C HamanoMay 21, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.