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
Junio C Hamano <gitster@pobox.com>
Date
May 21, 2015, 18:33 UTC
Message-ID
<xmqq7fs1kcfd.fsf@gitster.dls.corp.google.com>
In-Reply-To
<20150521044532.GH23409@peff.net>
Jeff King <peff@peff.net> writes:
Show 22 quoted lines
> diff --git a/remote.c b/remote.c
> index dca3442..1b7051a 100644
> --- a/remote.c
> +++ b/remote.c
> @@ -1705,10 +1705,35 @@ int branch_merge_matches(struct branch *branch,
>  	return refname_match(branch->merge[i]->src, refname);
>  }
>  
> -const char *branch_get_upstream(struct branch *branch)
> +__attribute((format (printf,2,3)))
> +static const char *error_buf(struct strbuf *err, const char *fmt, ...)
>  {
> -	if (!branch || !branch->merge || !branch->merge[0])
> -		return NULL;
> +	if (err) {
> +		va_list ap;
> +		va_start(ap, fmt);
> +		strbuf_vaddf(err, fmt, ap);
> +		va_end(ap);
> +	}
> +	return NULL;
> +}

Many of our functions return -1 to signal an error, and that is why it makes sense for our error() helper to return -1 to save code in the caller, but only because the callers of this private helper use a NULL to signal an error, this also returns NULL. If we were to use the "callers can opt into detailed message by passing strbuf" pattern more widely, we would want a variant of the above that returns -1, too. And such a helper would do the same thing as above, with only difference from the above is to return -1.

It's a shame that we have to return something from this function, whose primary purpose is "we may or may not want an error message in a strbuf, so format the message when and only when we give you a strbuf", but C forces us to make it "always return NULL to signal an error to the caller, and optionally format the message into a strbuf if given".

And the name of this helper function only captures the "optionally format the message" part, not the "always return NULL" part.

Show 19 quoted lines
> +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 (!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,
> +				 _("upstream branch '%s' not stored as a remote-tracking branch"),
> +				 branch->merge[0]->src);
> +	}
> +
>  	return branch->merge[0]->dst;
>  }

This is a faithful conversion of what the get_upstream_branch() used to do, but that ref_exists() check and the error checking there look somewhat out of place.

It makes the reader wonder what should happen when "branch->refname" does not exist as a ref, but "branch->merge[0]->dst" can be fully dereferenced. Should it be an error, or if it is OK, the reason why it is OK is...?

Previous: Jeff KingNext: Jeff King
Message 15 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.