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

Re: [PATCH 6/6] update-ref: add support for 'symref-update' command

From
Patrick Steinhardt <ps@pks.im>
Date
May 16, 2024, 11:09 UTC
Message-ID
<ZkXpcvF6dxGr6qmj@tanuki>
In-Reply-To
<20240514124411.1037019-7-knayak@gitlab.com>
On Tue, May 14, 2024 at 02:44:11PM +0200, Karthik Nayak wrote:
Show 13 quoted lines
> From: Karthik Nayak <karthik.188@gmail.com>
> 
> Add 'symref-update' command to the '--stdin' mode of 'git-update-ref' to
> allow updates of symbolic refs. The 'symref-update' command takes in a
> <new-target>, which the <ref> will be updated to. If the <ref> doesn't
> exist it will be created.
> 
> It also optionally takes either an `ref <old-target>` or `oid
> <old-oid>`. If the <old-target> is provided, it checks to see if the
> <ref> targets the <old-target> before the update. If <old-oid> is provided
> it checks <ref> to ensure that it is a regular ref and <old-oid> is the
> OID before the update. This by extension also means that this when a
> zero <old-oid> is provided, it ensures that the ref didn't exist before.

It's somewhat unfortunate that the syntax diverges from the "update" command. "update" also has essentially the same issue now, that we cannot verify that its old value is a symref, right? Can we fix that in a backwards compatible way?

It would also be great to explain why exactly the syntax needs to diverge.

Show 6 quoted lines
> The command allows users to perform symbolic ref updates within a
> transaction. This provides atomicity and allows users to perform a set
> of operations together.
> 
> This command will also support deref mode, to ensure that we can update
> dereferenced regular refs to symrefs.
Will it support deref mode or does it support it with this patch?
Show 44 quoted lines
> diff --git a/builtin/update-ref.c b/builtin/update-ref.c
> index 16d184603b..389136dc2f 100644
> --- a/builtin/update-ref.c
> +++ b/builtin/update-ref.c
> @@ -98,6 +98,41 @@ static char *parse_next_refname(const char **next)
>  	return parse_refname(next);
>  }
>  
> +/*
> + * Wrapper around parse_arg which skips the next delimiter.
> + */
> +static char *parse_next_arg(const char **next)
> +{
> +	struct strbuf arg = STRBUF_INIT;
> +
> +	if (line_termination) {
> +		/* Without -z, consume SP and use next argument */
> +		if (!**next || **next == line_termination)
> +			return NULL;
> +		if (**next != ' ')
> +			die("expected SP but got: %s", *next);
> +	} else {
> +		/* With -z, read the next NUL-terminated line */
> +		if (**next)
> +			return NULL;
> +	}
> +	/* Skip the delimiter */
> +	(*next)++;
> +
> +	if (line_termination) {
> +		/* Without -z, use the next argument */
> +		*next = parse_arg(*next, &arg);
> +	} else {
> +		/* With -z, use everything up to the next NUL */
> +		strbuf_addstr(&arg, *next);
> +		*next += arg.len;
> +	}
> +
> +	if (arg.len)
> +		return strbuf_detach(&arg, NULL);
> +	return NULL;
> +}
> +
>  
There's an extra newline here.
Show 33 quoted lines
>  /*
>   * The value being parsed is <old-oid> (as opposed to <new-oid>; the
> @@ -237,6 +272,55 @@ static void parse_cmd_update(struct ref_transaction *transaction,
>  	strbuf_release(&err);
>  }
>  
> +static void parse_cmd_symref_update(struct ref_transaction *transaction,
> +				    const char *next, const char *end)
> +{
> +	char *refname, *new_target, *old_arg;
> +	char *old_target = NULL;
> +	struct strbuf err = STRBUF_INIT;
> +	struct object_id old_oid;
> +	int have_old = 0;
> +
> +	refname = parse_refname(&next);
> +	if (!refname)
> +		die("symref-update: missing <ref>");
> +
> +	new_target = parse_next_refname(&next);
> +	if (!new_target)
> +		die("symref-update %s: missing <new-target>", refname);
> +
> +	old_arg = parse_next_arg(&next);
> +	if (old_arg) {
> +		old_target = parse_next_refname(&next);
> +		if (!old_target)
> +			die("symref-update %s: expected old value", refname);
> +
> +		if (!strcmp(old_arg, "oid") &&
> +		    !repo_get_oid(the_repository, old_target, &old_oid)) {
> +			old_target = NULL;
> +			have_old = 1;

This one feels weird to me. Shouldn't we return an error in case we are unable to parse the old OID?

> +		} else if (strcmp(old_arg, "ref"))
> +			die("symref-update %s: invalid arg '%s' for old value", refname, old_arg);
When one of the branches has curly braces, then all branches should.
Show 9 quoted lines
> +	}
> +
> +	if (*next != line_termination)
> +		die("symref-update %s: extra input: %s", refname, next);
> +
> +	if (ref_transaction_update(transaction, refname, NULL,
> +				   have_old ? &old_oid : NULL,
> +				   new_target, old_target,
> +				   update_flags |= create_reflog_flag,
This should be `update_flags | create_reflog_flag`, shouldn't it?
Patrick
Previous: Karthik NayakNext: Karthik Nayak
Message 16 of 50 in “update-ref: add symref support for --stdin”
  1. 0/6 update-ref: add symref support for --stdinKarthik Nayak, May 14, 2024
  2. 1/6 refs: create and use `ref_update_ref_must_exist()`Karthik Nayak, May 14, 2024
  3. Patrick SteinhardtMay 16, 2024
  4. Karthik NayakMay 17, 2024
  5. 2/6 update-ref: add support for 'symref-verify' commandKarthik Nayak, May 14, 2024
  6. Patrick SteinhardtMay 16, 2024
  7. Karthik NayakMay 17, 2024
  8. Patrick SteinhardtMay 21, 2024
  9. 3/6 update-ref: add support for 'symref-delete' commandKarthik Nayak, May 14, 2024
  10. Patrick SteinhardtMay 16, 2024
  11. 4/6 update-ref: add support for 'symref-create' commandKarthik Nayak, May 14, 2024
  12. Patrick SteinhardtMay 16, 2024
  13. Karthik NayakMay 19, 2024
  14. 5/6 reftable: pick either 'oid' or 'target' for new updatesKarthik Nayak, May 14, 2024
  15. 6/6 update-ref: add support for 'symref-update' commandKarthik Nayak, May 14, 2024
  16. Patrick SteinhardtMay 16, 2024
  17. Karthik NayakMay 21, 2024
  18. Karthik NayakMay 22, 2024
  19. 0/6 update-ref: add symref support for --stdinKarthik Nayak, May 22, 2024
  20. 1/6 refs: create and use `ref_update_expects_existing_old_ref()`Karthik Nayak, May 22, 2024
  21. 2/6 update-ref: add support for 'symref-verify' commandKarthik Nayak, May 22, 2024
  22. 3/6 update-ref: add support for 'symref-delete' commandKarthik Nayak, May 22, 2024
  23. 4/6 update-ref: add support for 'symref-create' commandKarthik Nayak, May 22, 2024
  24. 5/6 reftable: pick either 'oid' or 'target' for new updatesKarthik Nayak, May 22, 2024
  25. 6/6 update-ref: add support for 'symref-update' commandKarthik Nayak, May 22, 2024
  26. Junio C HamanoMay 25, 2024
  27. Karthik NayakMay 29, 2024
  28. Junio C HamanoMay 23, 2024
  29. Karthik NayakMay 23, 2024
  30. Junio C HamanoMay 23, 2024
  31. Karthik NayakMay 23, 2024
  32. Eric SunshineMay 23, 2024
  33. Junio C HamanoMay 23, 2024
  34. Eric SunshineMay 23, 2024
  35. Junio C HamanoMay 23, 2024
  36. Junio C HamanoMay 23, 2024
  37. Junio C HamanoMay 23, 2024
  38. 0/6 update-ref: add symref support for --stdinKarthik Nayak, May 30, 2024
  39. Patrick SteinhardtJun 5, 2024
  40. 1/6 refs: create and use `ref_update_expects_existing_old_ref()`Karthik Nayak, May 30, 2024
  41. 2/6 update-ref: add support for 'symref-verify' commandKarthik Nayak, May 30, 2024
  42. 3/6 update-ref: add support for 'symref-delete' commandKarthik Nayak, May 30, 2024
  43. Patrick SteinhardtJun 5, 2024
  44. Karthik NayakJun 5, 2024
  45. Junio C HamanoJun 5, 2024
  46. 4/6 update-ref: add support for 'symref-create' commandKarthik Nayak, May 30, 2024
  47. Patrick SteinhardtJun 5, 2024
  48. 5/6 reftable: pick either 'oid' or 'target' for new updatesKarthik Nayak, May 30, 2024
  49. 6/6 update-ref: add support for 'symref-update' commandKarthik Nayak, May 30, 2024
  50. Patrick SteinhardtJun 5, 2024

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.