From: Karthik Nayak <karthik.188@xxxxxxxxx> The `parse_next_oid` is used for parsing the next oid present in the input buffer. Extend this function to also parse refnames in the form `ref:<ref_target>`. This will be used in the upcoming commits to add symref support to the existing update-ref commands. Since `parse_next_oid` now also parses refs apart from oids, we rename the function to a more apt name `parse_next_arg`. Signed-off-by: Karthik Nayak <karthik.188@xxxxxxxxx> --- builtin/update-ref.c | 58 ++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 21fdbf6ac8..98ec356394 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -88,6 +88,11 @@ static char *parse_refname(const char **next) */ #define PARSE_SHA1_ALLOW_EMPTY 0x02 +/* + * Parse refname targets using the ref:<ref_target> format. + */ +#define PARSE_REFNAME_TARGETS 0x04 + /* * Parse an argument separator followed by the next argument, if any. * If there is an argument, convert it to a SHA-1, write it to sha1, @@ -95,10 +100,13 @@ static char *parse_refname(const char **next) * return 0. If there is no argument at all (not even the empty * string), return 1 and leave *next unchanged. If the value is * provided but cannot be converted to a SHA-1, die. flags can - * include PARSE_SHA1_OLD and/or PARSE_SHA1_ALLOW_EMPTY. + * include PARSE_SHA1_OLD and/or PARSE_SHA1_ALLOW_EMPTY and/or + * PARSE_REFNAME_TARGETS. When PARSE_REFNAME_TARGETS is set, parse + * the argument as `ref:<refname>` and store the refname into + * the target strbuf. */ -static int parse_next_oid(const char **next, const char *end, - struct object_id *oid, +static int parse_next_arg(const char **next, const char *end, + struct object_id *oid, struct strbuf *target, const char *command, const char *refname, int flags) { @@ -118,8 +126,17 @@ static int parse_next_oid(const char **next, const char *end, (*next)++; *next = parse_arg(*next, &arg); if (arg.len) { - if (repo_get_oid(the_repository, arg.buf, oid)) - goto invalid; + if (repo_get_oid(the_repository, arg.buf, oid)) { + const char *value; + if (flags & PARSE_REFNAME_TARGETS && + skip_prefix(arg.buf, "ref:", &value)) { + if (check_refname_format(value, REFNAME_ALLOW_ONELEVEL)) + die("invalid ref format: %s", value); + strbuf_addstr(target, value); + } else { + goto invalid; + } + } } else { /* Without -z, an empty value means all zeros: */ oidclr(oid); @@ -136,8 +153,17 @@ static int parse_next_oid(const char **next, const char *end, *next += arg.len; if (arg.len) { - if (repo_get_oid(the_repository, arg.buf, oid)) - goto invalid; + if (repo_get_oid(the_repository, arg.buf, oid)) { + const char *value; + if (flags & PARSE_REFNAME_TARGETS && + skip_prefix(arg.buf, "ref:", &value)) { + if (check_refname_format(value, REFNAME_ALLOW_ONELEVEL)) + die("invalid ref format: %s", value); + strbuf_addstr(target, value); + } else { + goto invalid; + } + } } else if (flags & PARSE_SHA1_ALLOW_EMPTY) { /* With -z, treat an empty value as all zeros: */ warning("%s %s: missing <new-oid>, treating as zero", @@ -192,12 +218,12 @@ static void parse_cmd_update(struct ref_transaction *transaction, if (!refname) die("update: missing <ref>"); - if (parse_next_oid(&next, end, &new_oid, "update", refname, - PARSE_SHA1_ALLOW_EMPTY)) + if (parse_next_arg(&next, end, &new_oid, NULL, + "update", refname, PARSE_SHA1_ALLOW_EMPTY)) die("update %s: missing <new-oid>", refname); - have_old = !parse_next_oid(&next, end, &old_oid, "update", refname, - PARSE_SHA1_OLD); + have_old = !parse_next_arg(&next, end, &old_oid, NULL, + "update", refname, PARSE_SHA1_OLD); if (*next != line_termination) die("update %s: extra input: %s", refname, next); @@ -225,7 +251,7 @@ static void parse_cmd_create(struct ref_transaction *transaction, if (!refname) die("create: missing <ref>"); - if (parse_next_oid(&next, end, &new_oid, "create", refname, 0)) + if (parse_next_arg(&next, end, &new_oid, NULL, "create", refname, 0)) die("create %s: missing <new-oid>", refname); if (is_null_oid(&new_oid)) @@ -256,8 +282,8 @@ static void parse_cmd_delete(struct ref_transaction *transaction, if (!refname) die("delete: missing <ref>"); - if (parse_next_oid(&next, end, &old_oid, "delete", refname, - PARSE_SHA1_OLD)) { + if (parse_next_arg(&next, end, &old_oid, NULL, + "delete", refname, PARSE_SHA1_OLD)) { have_old = 0; } else { if (is_null_oid(&old_oid)) @@ -289,8 +315,8 @@ static void parse_cmd_verify(struct ref_transaction *transaction, if (!refname) die("verify: missing <ref>"); - if (parse_next_oid(&next, end, &old_oid, "verify", refname, - PARSE_SHA1_OLD)) + if (parse_next_arg(&next, end, &old_oid, NULL, + "verify", refname, PARSE_SHA1_OLD)) oidclr(&old_oid); if (*next != line_termination) -- 2.43.GIT