diff options
Diffstat (limited to 'refs.c')
-rw-r--r-- | refs.c | 158 |
1 files changed, 146 insertions, 12 deletions
@@ -9,6 +9,7 @@ #include "iterator.h" #include "refs.h" #include "refs/refs-internal.h" +#include "run-command.h" #include "object-store.h" #include "object.h" #include "tag.h" @@ -16,6 +17,7 @@ #include "worktree.h" #include "argv-array.h" #include "repository.h" +#include "sigchain.h" /* * List of all available backends @@ -339,7 +341,7 @@ enum peel_status peel_object(const struct object_id *name, struct object_id *oid if (o->type == OBJ_NONE) { int type = oid_object_info(the_repository, name, NULL); - if (type < 0 || !object_as_type(the_repository, o, type, 0)) + if (type < 0 || !object_as_type(o, type, 0)) return PEEL_INVALID; } @@ -560,6 +562,36 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) argv_array_pushf(prefixes, *p, len, prefix); } +char *repo_default_branch_name(struct repository *r) +{ + const char *config_key = "init.defaultbranch"; + const char *config_display_key = "init.defaultBranch"; + char *ret = NULL, *full_ref; + + if (repo_config_get_string(r, config_key, &ret) < 0) + die(_("could not retrieve `%s`"), config_display_key); + + if (!ret) + ret = xstrdup("master"); + + full_ref = xstrfmt("refs/heads/%s", ret); + if (check_refname_format(full_ref, 0)) + die(_("invalid branch name: %s = %s"), config_display_key, ret); + free(full_ref); + + return ret; +} + +const char *git_default_branch_name(void) +{ + static char *ret; + + if (!ret) + ret = repo_default_branch_name(the_repository); + + return ret; +} + /* * *string and *len will only be substituted, and *string returned (for * later free()ing) if the string passed in is a magic short-hand form @@ -870,7 +902,7 @@ int delete_ref(const char *msg, const char *refname, old_oid, flags); } -void copy_reflog_msg(struct strbuf *sb, const char *msg) +static void copy_reflog_msg(struct strbuf *sb, const char *msg) { char c; int wasspace = 1; @@ -887,6 +919,15 @@ void copy_reflog_msg(struct strbuf *sb, const char *msg) strbuf_rtrim(sb); } +static char *normalize_reflog_message(const char *msg) +{ + struct strbuf sb = STRBUF_INIT; + + if (msg && *msg) + copy_reflog_msg(&sb, msg); + return strbuf_detach(&sb, NULL); +} + int should_autocreate_reflog(const char *refname) { switch (log_all_ref_updates) { @@ -1092,7 +1133,7 @@ struct ref_update *ref_transaction_add_update( oidcpy(&update->new_oid, new_oid); if (flags & REF_HAVE_OLD) oidcpy(&update->old_oid, old_oid); - update->msg = xstrdup_or_null(msg); + update->msg = normalize_reflog_message(msg); return update; } @@ -1951,9 +1992,14 @@ int refs_create_symref(struct ref_store *refs, const char *refs_heads_master, const char *logmsg) { - return refs->be->create_symref(refs, ref_target, - refs_heads_master, - logmsg); + char *msg; + int retval; + + msg = normalize_reflog_message(logmsg); + retval = refs->be->create_symref(refs, ref_target, refs_heads_master, + msg); + free(msg); + return retval; } int create_symref(const char *ref_target, const char *refs_heads_master, @@ -1986,10 +2032,65 @@ int ref_update_reject_duplicates(struct string_list *refnames, return 0; } +static const char hook_not_found; +static const char *hook; + +static int run_transaction_hook(struct ref_transaction *transaction, + const char *state) +{ + struct child_process proc = CHILD_PROCESS_INIT; + struct strbuf buf = STRBUF_INIT; + int ret = 0, i; + + if (hook == &hook_not_found) + return ret; + if (!hook) + hook = find_hook("reference-transaction"); + if (!hook) { + hook = &hook_not_found; + return ret; + } + + argv_array_pushl(&proc.args, hook, state, NULL); + proc.in = -1; + proc.stdout_to_stderr = 1; + proc.trace2_hook_name = "reference-transaction"; + + ret = start_command(&proc); + if (ret) + return ret; + + sigchain_push(SIGPIPE, SIG_IGN); + + for (i = 0; i < transaction->nr; i++) { + struct ref_update *update = transaction->updates[i]; + + strbuf_reset(&buf); + strbuf_addf(&buf, "%s %s %s\n", + oid_to_hex(&update->old_oid), + oid_to_hex(&update->new_oid), + update->refname); + + if (write_in_full(proc.in, buf.buf, buf.len) < 0) { + if (errno != EPIPE) + ret = -1; + break; + } + } + + close(proc.in); + sigchain_pop(SIGPIPE); + strbuf_release(&buf); + + ret |= finish_command(&proc); + return ret; +} + int ref_transaction_prepare(struct ref_transaction *transaction, struct strbuf *err) { struct ref_store *refs = transaction->ref_store; + int ret; switch (transaction->state) { case REF_TRANSACTION_OPEN: @@ -2012,7 +2113,17 @@ int ref_transaction_prepare(struct ref_transaction *transaction, return -1; } - return refs->be->transaction_prepare(refs, transaction, err); + ret = refs->be->transaction_prepare(refs, transaction, err); + if (ret) + return ret; + + ret = run_transaction_hook(transaction, "prepared"); + if (ret) { + ref_transaction_abort(transaction, err); + die(_("ref updates aborted by hook")); + } + + return 0; } int ref_transaction_abort(struct ref_transaction *transaction, @@ -2036,6 +2147,8 @@ int ref_transaction_abort(struct ref_transaction *transaction, break; } + run_transaction_hook(transaction, "aborted"); + ref_transaction_free(transaction); return ret; } @@ -2064,7 +2177,10 @@ int ref_transaction_commit(struct ref_transaction *transaction, break; } - return refs->be->transaction_finish(refs, transaction, err); + ret = refs->be->transaction_finish(refs, transaction, err); + if (!ret) + run_transaction_hook(transaction, "committed"); + return ret; } int refs_verify_refname_available(struct ref_store *refs, @@ -2268,10 +2384,16 @@ int initial_ref_transaction_commit(struct ref_transaction *transaction, return refs->be->initial_transaction_commit(refs, transaction, err); } -int refs_delete_refs(struct ref_store *refs, const char *msg, +int refs_delete_refs(struct ref_store *refs, const char *logmsg, struct string_list *refnames, unsigned int flags) { - return refs->be->delete_refs(refs, msg, refnames, flags); + char *msg; + int retval; + + msg = normalize_reflog_message(logmsg); + retval = refs->be->delete_refs(refs, msg, refnames, flags); + free(msg); + return retval; } int delete_refs(const char *msg, struct string_list *refnames, @@ -2283,7 +2405,13 @@ int delete_refs(const char *msg, struct string_list *refnames, int refs_rename_ref(struct ref_store *refs, const char *oldref, const char *newref, const char *logmsg) { - return refs->be->rename_ref(refs, oldref, newref, logmsg); + char *msg; + int retval; + + msg = normalize_reflog_message(logmsg); + retval = refs->be->rename_ref(refs, oldref, newref, msg); + free(msg); + return retval; } int rename_ref(const char *oldref, const char *newref, const char *logmsg) @@ -2294,7 +2422,13 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg) int refs_copy_existing_ref(struct ref_store *refs, const char *oldref, const char *newref, const char *logmsg) { - return refs->be->copy_ref(refs, oldref, newref, logmsg); + char *msg; + int retval; + + msg = normalize_reflog_message(logmsg); + retval = refs->be->copy_ref(refs, oldref, newref, msg); + free(msg); + return retval; } int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg) |