summaryrefslogtreecommitdiff
path: root/refs.c
diff options
context:
space:
mode:
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c158
1 files changed, 146 insertions, 12 deletions
diff --git a/refs.c b/refs.c
index 224ff66c7b..89814c7be4 100644
--- a/refs.c
+++ b/refs.c
@@ -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)