diff options
Diffstat (limited to 'refs.c')
-rw-r--r-- | refs.c | 108 |
1 files changed, 105 insertions, 3 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 @@ -1986,10 +2018,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 +2099,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 +2133,8 @@ int ref_transaction_abort(struct ref_transaction *transaction, break; } + run_transaction_hook(transaction, "aborted"); + ref_transaction_free(transaction); return ret; } @@ -2064,7 +2163,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, |