about summary refs log tree commit diff
path: root/third_party/git/builtin/update-ref.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/git/builtin/update-ref.c')
-rw-r--r--third_party/git/builtin/update-ref.c560
1 files changed, 0 insertions, 560 deletions
diff --git a/third_party/git/builtin/update-ref.c b/third_party/git/builtin/update-ref.c
deleted file mode 100644
index 8a2df4459c66..000000000000
--- a/third_party/git/builtin/update-ref.c
+++ /dev/null
@@ -1,560 +0,0 @@
-#include "cache.h"
-#include "config.h"
-#include "refs.h"
-#include "builtin.h"
-#include "parse-options.h"
-#include "quote.h"
-#include "strvec.h"
-
-static const char * const git_update_ref_usage[] = {
-	N_("git update-ref [<options>] -d <refname> [<old-val>]"),
-	N_("git update-ref [<options>]    <refname> <new-val> [<old-val>]"),
-	N_("git update-ref [<options>] --stdin [-z]"),
-	NULL
-};
-
-static char line_termination = '\n';
-static unsigned int update_flags;
-static unsigned int default_flags;
-static unsigned create_reflog_flag;
-static const char *msg;
-
-/*
- * Parse one whitespace- or NUL-terminated, possibly C-quoted argument
- * and append the result to arg.  Return a pointer to the terminator.
- * Die if there is an error in how the argument is C-quoted.  This
- * function is only used if not -z.
- */
-static const char *parse_arg(const char *next, struct strbuf *arg)
-{
-	if (*next == '"') {
-		const char *orig = next;
-
-		if (unquote_c_style(arg, next, &next))
-			die("badly quoted argument: %s", orig);
-		if (*next && !isspace(*next))
-			die("unexpected character after quoted argument: %s", orig);
-	} else {
-		while (*next && !isspace(*next))
-			strbuf_addch(arg, *next++);
-	}
-
-	return next;
-}
-
-/*
- * Parse the reference name immediately after "command SP".  If not
- * -z, then handle C-quoting.  Return a pointer to a newly allocated
- * string containing the name of the reference, or NULL if there was
- * an error.  Update *next to point at the character that terminates
- * the argument.  Die if C-quoting is malformed or the reference name
- * is invalid.
- */
-static char *parse_refname(const char **next)
-{
-	struct strbuf ref = STRBUF_INIT;
-
-	if (line_termination) {
-		/* Without -z, use the next argument */
-		*next = parse_arg(*next, &ref);
-	} else {
-		/* With -z, use everything up to the next NUL */
-		strbuf_addstr(&ref, *next);
-		*next += ref.len;
-	}
-
-	if (!ref.len) {
-		strbuf_release(&ref);
-		return NULL;
-	}
-
-	if (check_refname_format(ref.buf, REFNAME_ALLOW_ONELEVEL))
-		die("invalid ref format: %s", ref.buf);
-
-	return strbuf_detach(&ref, NULL);
-}
-
-/*
- * The value being parsed is <oldvalue> (as opposed to <newvalue>; the
- * difference affects which error messages are generated):
- */
-#define PARSE_SHA1_OLD 0x01
-
-/*
- * For backwards compatibility, accept an empty string for update's
- * <newvalue> in binary mode to be equivalent to specifying zeros.
- */
-#define PARSE_SHA1_ALLOW_EMPTY 0x02
-
-/*
- * 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,
- * set *next to point at the character terminating the argument, and
- * 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.
- */
-static int parse_next_oid(const char **next, const char *end,
-			  struct object_id *oid,
-			  const char *command, const char *refname,
-			  int flags)
-{
-	struct strbuf arg = STRBUF_INIT;
-	int ret = 0;
-
-	if (*next == end)
-		goto eof;
-
-	if (line_termination) {
-		/* Without -z, consume SP and use next argument */
-		if (!**next || **next == line_termination)
-			return 1;
-		if (**next != ' ')
-			die("%s %s: expected SP but got: %s",
-			    command, refname, *next);
-		(*next)++;
-		*next = parse_arg(*next, &arg);
-		if (arg.len) {
-			if (get_oid(arg.buf, oid))
-				goto invalid;
-		} else {
-			/* Without -z, an empty value means all zeros: */
-			oidclr(oid);
-		}
-	} else {
-		/* With -z, read the next NUL-terminated line */
-		if (**next)
-			die("%s %s: expected NUL but got: %s",
-			    command, refname, *next);
-		(*next)++;
-		if (*next == end)
-			goto eof;
-		strbuf_addstr(&arg, *next);
-		*next += arg.len;
-
-		if (arg.len) {
-			if (get_oid(arg.buf, oid))
-				goto invalid;
-		} else if (flags & PARSE_SHA1_ALLOW_EMPTY) {
-			/* With -z, treat an empty value as all zeros: */
-			warning("%s %s: missing <newvalue>, treating as zero",
-				command, refname);
-			oidclr(oid);
-		} else {
-			/*
-			 * With -z, an empty non-required value means
-			 * unspecified:
-			 */
-			ret = 1;
-		}
-	}
-
-	strbuf_release(&arg);
-
-	return ret;
-
- invalid:
-	die(flags & PARSE_SHA1_OLD ?
-	    "%s %s: invalid <oldvalue>: %s" :
-	    "%s %s: invalid <newvalue>: %s",
-	    command, refname, arg.buf);
-
- eof:
-	die(flags & PARSE_SHA1_OLD ?
-	    "%s %s: unexpected end of input when reading <oldvalue>" :
-	    "%s %s: unexpected end of input when reading <newvalue>",
-	    command, refname);
-}
-
-
-/*
- * The following five parse_cmd_*() functions parse the corresponding
- * command.  In each case, next points at the character following the
- * command name and the following space.  They each return a pointer
- * to the character terminating the command, and die with an
- * explanatory message if there are any parsing problems.  All of
- * these functions handle either text or binary format input,
- * depending on how line_termination is set.
- */
-
-static void parse_cmd_update(struct ref_transaction *transaction,
-			     const char *next, const char *end)
-{
-	struct strbuf err = STRBUF_INIT;
-	char *refname;
-	struct object_id new_oid, old_oid;
-	int have_old;
-
-	refname = parse_refname(&next);
-	if (!refname)
-		die("update: missing <ref>");
-
-	if (parse_next_oid(&next, end, &new_oid, "update", refname,
-			   PARSE_SHA1_ALLOW_EMPTY))
-		die("update %s: missing <newvalue>", refname);
-
-	have_old = !parse_next_oid(&next, end, &old_oid, "update", refname,
-				   PARSE_SHA1_OLD);
-
-	if (*next != line_termination)
-		die("update %s: extra input: %s", refname, next);
-
-	if (ref_transaction_update(transaction, refname,
-				   &new_oid, have_old ? &old_oid : NULL,
-				   update_flags | create_reflog_flag,
-				   msg, &err))
-		die("%s", err.buf);
-
-	update_flags = default_flags;
-	free(refname);
-	strbuf_release(&err);
-}
-
-static void parse_cmd_create(struct ref_transaction *transaction,
-			     const char *next, const char *end)
-{
-	struct strbuf err = STRBUF_INIT;
-	char *refname;
-	struct object_id new_oid;
-
-	refname = parse_refname(&next);
-	if (!refname)
-		die("create: missing <ref>");
-
-	if (parse_next_oid(&next, end, &new_oid, "create", refname, 0))
-		die("create %s: missing <newvalue>", refname);
-
-	if (is_null_oid(&new_oid))
-		die("create %s: zero <newvalue>", refname);
-
-	if (*next != line_termination)
-		die("create %s: extra input: %s", refname, next);
-
-	if (ref_transaction_create(transaction, refname, &new_oid,
-				   update_flags | create_reflog_flag,
-				   msg, &err))
-		die("%s", err.buf);
-
-	update_flags = default_flags;
-	free(refname);
-	strbuf_release(&err);
-}
-
-static void parse_cmd_delete(struct ref_transaction *transaction,
-			     const char *next, const char *end)
-{
-	struct strbuf err = STRBUF_INIT;
-	char *refname;
-	struct object_id old_oid;
-	int have_old;
-
-	refname = parse_refname(&next);
-	if (!refname)
-		die("delete: missing <ref>");
-
-	if (parse_next_oid(&next, end, &old_oid, "delete", refname,
-			   PARSE_SHA1_OLD)) {
-		have_old = 0;
-	} else {
-		if (is_null_oid(&old_oid))
-			die("delete %s: zero <oldvalue>", refname);
-		have_old = 1;
-	}
-
-	if (*next != line_termination)
-		die("delete %s: extra input: %s", refname, next);
-
-	if (ref_transaction_delete(transaction, refname,
-				   have_old ? &old_oid : NULL,
-				   update_flags, msg, &err))
-		die("%s", err.buf);
-
-	update_flags = default_flags;
-	free(refname);
-	strbuf_release(&err);
-}
-
-static void parse_cmd_verify(struct ref_transaction *transaction,
-			     const char *next, const char *end)
-{
-	struct strbuf err = STRBUF_INIT;
-	char *refname;
-	struct object_id old_oid;
-
-	refname = parse_refname(&next);
-	if (!refname)
-		die("verify: missing <ref>");
-
-	if (parse_next_oid(&next, end, &old_oid, "verify", refname,
-			   PARSE_SHA1_OLD))
-		oidclr(&old_oid);
-
-	if (*next != line_termination)
-		die("verify %s: extra input: %s", refname, next);
-
-	if (ref_transaction_verify(transaction, refname, &old_oid,
-				   update_flags, &err))
-		die("%s", err.buf);
-
-	update_flags = default_flags;
-	free(refname);
-	strbuf_release(&err);
-}
-
-static void parse_cmd_option(struct ref_transaction *transaction,
-			     const char *next, const char *end)
-{
-	const char *rest;
-	if (skip_prefix(next, "no-deref", &rest) && *rest == line_termination)
-		update_flags |= REF_NO_DEREF;
-	else
-		die("option unknown: %s", next);
-}
-
-static void parse_cmd_start(struct ref_transaction *transaction,
-			    const char *next, const char *end)
-{
-	if (*next != line_termination)
-		die("start: extra input: %s", next);
-	puts("start: ok");
-}
-
-static void parse_cmd_prepare(struct ref_transaction *transaction,
-			      const char *next, const char *end)
-{
-	struct strbuf error = STRBUF_INIT;
-	if (*next != line_termination)
-		die("prepare: extra input: %s", next);
-	if (ref_transaction_prepare(transaction, &error))
-		die("prepare: %s", error.buf);
-	puts("prepare: ok");
-}
-
-static void parse_cmd_abort(struct ref_transaction *transaction,
-			    const char *next, const char *end)
-{
-	struct strbuf error = STRBUF_INIT;
-	if (*next != line_termination)
-		die("abort: extra input: %s", next);
-	if (ref_transaction_abort(transaction, &error))
-		die("abort: %s", error.buf);
-	puts("abort: ok");
-}
-
-static void parse_cmd_commit(struct ref_transaction *transaction,
-			     const char *next, const char *end)
-{
-	struct strbuf error = STRBUF_INIT;
-	if (*next != line_termination)
-		die("commit: extra input: %s", next);
-	if (ref_transaction_commit(transaction, &error))
-		die("commit: %s", error.buf);
-	puts("commit: ok");
-	ref_transaction_free(transaction);
-}
-
-enum update_refs_state {
-	/* Non-transactional state open for updates. */
-	UPDATE_REFS_OPEN,
-	/* A transaction has been started. */
-	UPDATE_REFS_STARTED,
-	/* References are locked and ready for commit */
-	UPDATE_REFS_PREPARED,
-	/* Transaction has been committed or closed. */
-	UPDATE_REFS_CLOSED,
-};
-
-static const struct parse_cmd {
-	const char *prefix;
-	void (*fn)(struct ref_transaction *, const char *, const char *);
-	unsigned args;
-	enum update_refs_state state;
-} command[] = {
-	{ "update",  parse_cmd_update,  3, UPDATE_REFS_OPEN },
-	{ "create",  parse_cmd_create,  2, UPDATE_REFS_OPEN },
-	{ "delete",  parse_cmd_delete,  2, UPDATE_REFS_OPEN },
-	{ "verify",  parse_cmd_verify,  2, UPDATE_REFS_OPEN },
-	{ "option",  parse_cmd_option,  1, UPDATE_REFS_OPEN },
-	{ "start",   parse_cmd_start,   0, UPDATE_REFS_STARTED },
-	{ "prepare", parse_cmd_prepare, 0, UPDATE_REFS_PREPARED },
-	{ "abort",   parse_cmd_abort,   0, UPDATE_REFS_CLOSED },
-	{ "commit",  parse_cmd_commit,  0, UPDATE_REFS_CLOSED },
-};
-
-static void update_refs_stdin(void)
-{
-	struct strbuf input = STRBUF_INIT, err = STRBUF_INIT;
-	enum update_refs_state state = UPDATE_REFS_OPEN;
-	struct ref_transaction *transaction;
-	int i, j;
-
-	transaction = ref_transaction_begin(&err);
-	if (!transaction)
-		die("%s", err.buf);
-
-	/* Read each line dispatch its command */
-	while (!strbuf_getwholeline(&input, stdin, line_termination)) {
-		const struct parse_cmd *cmd = NULL;
-
-		if (*input.buf == line_termination)
-			die("empty command in input");
-		else if (isspace(*input.buf))
-			die("whitespace before command: %s", input.buf);
-
-		for (i = 0; i < ARRAY_SIZE(command); i++) {
-			const char *prefix = command[i].prefix;
-			char c;
-
-			if (!starts_with(input.buf, prefix))
-				continue;
-
-			/*
-			 * If the command has arguments, verify that it's
-			 * followed by a space. Otherwise, it shall be followed
-			 * by a line terminator.
-			 */
-			c = command[i].args ? ' ' : line_termination;
-			if (input.buf[strlen(prefix)] != c)
-				continue;
-
-			cmd = &command[i];
-			break;
-		}
-		if (!cmd)
-			die("unknown command: %s", input.buf);
-
-		/*
-		 * Read additional arguments if NUL-terminated. Do not raise an
-		 * error in case there is an early EOF to let the command
-		 * handle missing arguments with a proper error message.
-		 */
-		for (j = 1; line_termination == '\0' && j < cmd->args; j++)
-			if (strbuf_appendwholeline(&input, stdin, line_termination))
-				break;
-
-		switch (state) {
-		case UPDATE_REFS_OPEN:
-		case UPDATE_REFS_STARTED:
-			/* Do not downgrade a transaction to a non-transaction. */
-			if (cmd->state >= state)
-				state = cmd->state;
-			break;
-		case UPDATE_REFS_PREPARED:
-			if (cmd->state != UPDATE_REFS_CLOSED)
-				die("prepared transactions can only be closed");
-			state = cmd->state;
-			break;
-		case UPDATE_REFS_CLOSED:
-			die("transaction is closed");
-			break;
-		}
-
-		cmd->fn(transaction, input.buf + strlen(cmd->prefix) + !!cmd->args,
-			input.buf + input.len);
-	}
-
-	switch (state) {
-	case UPDATE_REFS_OPEN:
-		/* Commit by default if no transaction was requested. */
-		if (ref_transaction_commit(transaction, &err))
-			die("%s", err.buf);
-		ref_transaction_free(transaction);
-		break;
-	case UPDATE_REFS_STARTED:
-	case UPDATE_REFS_PREPARED:
-		/* If using a transaction, we want to abort it. */
-		if (ref_transaction_abort(transaction, &err))
-			die("%s", err.buf);
-		break;
-	case UPDATE_REFS_CLOSED:
-		/* Otherwise no need to do anything, the transaction was closed already. */
-		break;
-	}
-
-	strbuf_release(&err);
-	strbuf_release(&input);
-}
-
-int cmd_update_ref(int argc, const char **argv, const char *prefix)
-{
-	const char *refname, *oldval;
-	struct object_id oid, oldoid;
-	int delete = 0, no_deref = 0, read_stdin = 0, end_null = 0;
-	int create_reflog = 0;
-	struct option options[] = {
-		OPT_STRING( 'm', NULL, &msg, N_("reason"), N_("reason of the update")),
-		OPT_BOOL('d', NULL, &delete, N_("delete the reference")),
-		OPT_BOOL( 0 , "no-deref", &no_deref,
-					N_("update <refname> not the one it points to")),
-		OPT_BOOL('z', NULL, &end_null, N_("stdin has NUL-terminated arguments")),
-		OPT_BOOL( 0 , "stdin", &read_stdin, N_("read updates from stdin")),
-		OPT_BOOL( 0 , "create-reflog", &create_reflog, N_("create a reflog")),
-		OPT_END(),
-	};
-
-	git_config(git_default_config, NULL);
-	argc = parse_options(argc, argv, prefix, options, git_update_ref_usage,
-			     0);
-	if (msg && !*msg)
-		die("Refusing to perform update with empty message.");
-
-	create_reflog_flag = create_reflog ? REF_FORCE_CREATE_REFLOG : 0;
-
-	if (no_deref) {
-		default_flags = REF_NO_DEREF;
-		update_flags = default_flags;
-	}
-
-	if (read_stdin) {
-		if (delete || argc > 0)
-			usage_with_options(git_update_ref_usage, options);
-		if (end_null)
-			line_termination = '\0';
-		update_refs_stdin();
-		return 0;
-	}
-
-	if (end_null)
-		usage_with_options(git_update_ref_usage, options);
-
-	if (delete) {
-		if (argc < 1 || argc > 2)
-			usage_with_options(git_update_ref_usage, options);
-		refname = argv[0];
-		oldval = argv[1];
-	} else {
-		const char *value;
-		if (argc < 2 || argc > 3)
-			usage_with_options(git_update_ref_usage, options);
-		refname = argv[0];
-		value = argv[1];
-		oldval = argv[2];
-		if (get_oid(value, &oid))
-			die("%s: not a valid SHA1", value);
-	}
-
-	if (oldval) {
-		if (!*oldval)
-			/*
-			 * The empty string implies that the reference
-			 * must not already exist:
-			 */
-			oidclr(&oldoid);
-		else if (get_oid(oldval, &oldoid))
-			die("%s: not a valid old SHA1", oldval);
-	}
-
-	if (delete)
-		/*
-		 * For purposes of backwards compatibility, we treat
-		 * NULL_SHA1 as "don't care" here:
-		 */
-		return delete_ref(msg, refname,
-				  (oldval && !is_null_oid(&oldoid)) ? &oldoid : NULL,
-				  default_flags);
-	else
-		return update_ref(msg, refname, &oid, oldval ? &oldoid : NULL,
-				  default_flags | create_reflog_flag,
-				  UPDATE_REFS_DIE_ON_ERR);
-}