diff options
Diffstat (limited to 'builtin/update-ref.c')
| -rw-r--r-- | builtin/update-ref.c | 63 |
1 files changed, 51 insertions, 12 deletions
diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 4d35bdc4b4..195437e7c6 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -3,8 +3,10 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hash.h" +#include "hex.h" #include "refs.h" #include "object-name.h" #include "parse-options.h" @@ -13,7 +15,7 @@ static const char * const git_update_ref_usage[] = { N_("git update-ref [<options>] -d <refname> [<old-oid>]"), N_("git update-ref [<options>] <refname> <new-oid> [<old-oid>]"), - N_("git update-ref [<options>] --stdin [-z]"), + N_("git update-ref [<options>] --stdin [-z] [--batch-updates]"), NULL }; @@ -179,7 +181,8 @@ 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)) + if (repo_get_oid_with_flags(the_repository, arg.buf, oid, + GET_OID_SKIP_AMBIGUITY_CHECK)) goto invalid; } else { /* Without -z, an empty value means all zeros: */ @@ -197,7 +200,8 @@ 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)) + if (repo_get_oid_with_flags(the_repository, arg.buf, oid, + GET_OID_SKIP_AMBIGUITY_CHECK)) goto invalid; } else if (flags & PARSE_SHA1_ALLOW_EMPTY) { /* With -z, treat an empty value as all zeros: */ @@ -299,7 +303,8 @@ static void parse_cmd_symref_update(struct ref_transaction *transaction, die("symref-update %s: expected old value", refname); if (!strcmp(old_arg, "oid")) { - if (repo_get_oid(the_repository, old_target, &old_oid)) + if (repo_get_oid_with_flags(the_repository, old_target, &old_oid, + GET_OID_SKIP_AMBIGUITY_CHECK)) die("symref-update %s: invalid oid: %s", refname, old_target); have_old_oid = 1; @@ -500,7 +505,7 @@ static void parse_cmd_symref_verify(struct ref_transaction *transaction, */ old_target = parse_next_refname(&next); if (!old_target) - oidcpy(&old_oid, null_oid()); + oidcpy(&old_oid, null_oid(the_hash_algo)); if (*next != line_termination) die("symref-verify %s: extra input: %s", refname, next); @@ -562,6 +567,26 @@ static void parse_cmd_abort(struct ref_transaction *transaction, report_ok("abort"); } +static void print_rejected_refs(const char *refname, + const struct object_id *old_oid, + const struct object_id *new_oid, + const char *old_target, + const char *new_target, + enum ref_transaction_error err, + void *cb_data UNUSED) +{ + struct strbuf sb = STRBUF_INIT; + const char *reason = ref_transaction_error_msg(err); + + strbuf_addf(&sb, "rejected %s %s %s %s\n", refname, + new_oid ? oid_to_hex(new_oid) : new_target, + old_oid ? oid_to_hex(old_oid) : old_target, + reason); + + fwrite(sb.buf, sb.len, 1, stdout); + strbuf_release(&sb); +} + static void parse_cmd_commit(struct ref_transaction *transaction, const char *next, const char *end UNUSED) { @@ -570,6 +595,10 @@ static void parse_cmd_commit(struct ref_transaction *transaction, die("commit: extra input: %s", next); if (ref_transaction_commit(transaction, &error)) die("commit: %s", error.buf); + + ref_transaction_for_each_rejected_update(transaction, + print_rejected_refs, NULL); + report_ok("commit"); ref_transaction_free(transaction); } @@ -606,7 +635,7 @@ static const struct parse_cmd { { "commit", parse_cmd_commit, 0, UPDATE_REFS_CLOSED }, }; -static void update_refs_stdin(void) +static void update_refs_stdin(unsigned int flags) { struct strbuf input = STRBUF_INIT, err = STRBUF_INIT; enum update_refs_state state = UPDATE_REFS_OPEN; @@ -614,7 +643,7 @@ static void update_refs_stdin(void) int i, j; transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - 0, &err); + flags, &err); if (!transaction) die("%s", err.buf); @@ -682,7 +711,7 @@ static void update_refs_stdin(void) */ state = cmd->state; transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - 0, &err); + flags, &err); if (!transaction) die("%s", err.buf); @@ -698,6 +727,8 @@ static void update_refs_stdin(void) /* Commit by default if no transaction was requested. */ if (ref_transaction_commit(transaction, &err)) die("%s", err.buf); + ref_transaction_for_each_rejected_update(transaction, + print_rejected_refs, NULL); ref_transaction_free(transaction); break; case UPDATE_REFS_STARTED: @@ -724,6 +755,8 @@ int cmd_update_ref(int argc, struct object_id oid, oldoid; int delete = 0, no_deref = 0, read_stdin = 0, end_null = 0; int create_reflog = 0; + unsigned int flags = 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")), @@ -732,10 +765,12 @@ int cmd_update_ref(int argc, 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_BIT('0', "batch-updates", &flags, N_("batch reference updates"), + REF_TRANSACTION_ALLOW_FAILURE), OPT_END(), }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_update_ref_usage, 0); if (msg && !*msg) @@ -753,8 +788,10 @@ int cmd_update_ref(int argc, usage_with_options(git_update_ref_usage, options); if (end_null) line_termination = '\0'; - update_refs_stdin(); + update_refs_stdin(flags); return 0; + } else if (flags & REF_TRANSACTION_ALLOW_FAILURE) { + die("--batch-updates can only be used with --stdin"); } if (end_null) @@ -772,7 +809,8 @@ int cmd_update_ref(int argc, refname = argv[0]; value = argv[1]; oldval = argv[2]; - if (repo_get_oid(the_repository, value, &oid)) + if (repo_get_oid_with_flags(the_repository, value, &oid, + GET_OID_SKIP_AMBIGUITY_CHECK)) die("%s: not a valid SHA1", value); } @@ -783,7 +821,8 @@ int cmd_update_ref(int argc, * must not already exist: */ oidclr(&oldoid, the_repository->hash_algo); - else if (repo_get_oid(the_repository, oldval, &oldoid)) + else if (repo_get_oid_with_flags(the_repository, oldval, &oldoid, + GET_OID_SKIP_AMBIGUITY_CHECK)) die("%s: not a valid old SHA1", oldval); } |
