return xstrdup_or_null(result);
}
-char *resolve_refdup(const char *refname, int resolve_flags,
- struct object_id *oid, int *flags)
-{
- return refs_resolve_refdup(get_main_ref_store(the_repository),
- refname, resolve_flags,
- oid, flags);
-}
-
/* The argument to for_each_filter_refs */
struct for_each_ref_filter {
const char *pattern;
void *cb_data;
};
-int read_ref_full(const char *refname, int resolve_flags, struct object_id *oid, int *flags)
+int refs_read_ref_full(struct ref_store *refs, const char *refname,
+ int resolve_flags, struct object_id *oid, int *flags)
{
- struct ref_store *refs = get_main_ref_store(the_repository);
-
if (refs_resolve_ref_unsafe(refs, refname, resolve_flags,
oid, flags))
return 0;
return -1;
}
-int read_ref(const char *refname, struct object_id *oid)
+int refs_read_ref(struct ref_store *refs, const char *refname, struct object_id *oid)
{
- return read_ref_full(refname, RESOLVE_REF_READING, oid, NULL);
+ return refs_read_ref_full(refs, refname, RESOLVE_REF_READING, oid, NULL);
}
int refs_ref_exists(struct ref_store *refs, const char *refname)
NULL, NULL);
}
-int ref_exists(const char *refname)
-{
- return refs_ref_exists(get_main_ref_store(the_repository), refname);
-}
-
static int for_each_filter_refs(const char *refname,
const struct object_id *oid,
int flags, void *data)
if (!(flags & REF_ISSYMREF))
return 0;
- resolves_to = resolve_ref_unsafe(refname, 0, NULL, NULL);
+ resolves_to = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
+ refname, 0, NULL, NULL);
if (!resolves_to
|| (d->refname
? strcmp(resolves_to, d->refname)
data.refname = refname;
data.refnames = NULL;
data.msg_fmt = msg_fmt;
- for_each_rawref(warn_if_dangling_symref, &data);
+ refs_for_each_rawref(get_main_ref_store(the_repository),
+ warn_if_dangling_symref, &data);
}
void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames)
data.refname = NULL;
data.refnames = refnames;
data.msg_fmt = msg_fmt;
- for_each_rawref(warn_if_dangling_symref, &data);
+ refs_for_each_rawref(get_main_ref_store(the_repository),
+ warn_if_dangling_symref, &data);
}
int refs_for_each_tag_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
return refs_for_each_ref_in(refs, "refs/tags/", fn, cb_data);
}
-int for_each_tag_ref(each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_tag_ref(get_main_ref_store(the_repository), fn, cb_data);
-}
-
int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
{
return refs_for_each_ref_in(refs, "refs/heads/", fn, cb_data);
}
-int for_each_branch_ref(each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_branch_ref(get_main_ref_store(the_repository), fn, cb_data);
-}
-
int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
{
return refs_for_each_ref_in(refs, "refs/remotes/", fn, cb_data);
}
-int for_each_remote_ref(each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_remote_ref(get_main_ref_store(the_repository), fn, cb_data);
-}
-
-int head_ref_namespaced(each_ref_fn fn, void *cb_data)
+int refs_head_ref_namespaced(struct ref_store *refs, each_ref_fn fn, void *cb_data)
{
struct strbuf buf = STRBUF_INIT;
int ret = 0;
int flag;
strbuf_addf(&buf, "%sHEAD", get_git_namespace());
- if (!read_ref_full(buf.buf, RESOLVE_REF_READING, &oid, &flag))
+ if (!refs_read_ref_full(refs, buf.buf, RESOLVE_REF_READING, &oid, &flag))
ret = fn(buf.buf, &oid, flag, cb_data);
strbuf_release(&buf);
strbuf_release(&normalized_pattern);
}
-int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
- const char *prefix, void *cb_data)
+int refs_for_each_glob_ref_in(struct ref_store *refs, each_ref_fn fn,
+ const char *pattern, const char *prefix, void *cb_data)
{
struct strbuf real_pattern = STRBUF_INIT;
struct for_each_ref_filter filter;
filter.prefix = prefix;
filter.fn = fn;
filter.cb_data = cb_data;
- ret = for_each_ref(for_each_filter_refs, &filter);
+ ret = refs_for_each_ref(refs, for_each_filter_refs, &filter);
strbuf_release(&real_pattern);
return ret;
}
-int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
+int refs_for_each_glob_ref(struct ref_store *refs, each_ref_fn fn,
+ const char *pattern, void *cb_data)
{
- return for_each_glob_ref_in(fn, pattern, NULL, cb_data);
+ return refs_for_each_glob_ref_in(refs, fn, pattern, NULL, cb_data);
}
const char *prettify_refname(const char *name)
return 0;
}
-int delete_ref(const char *msg, const char *refname,
- const struct object_id *old_oid, unsigned int flags)
-{
- return refs_delete_ref(get_main_ref_store(the_repository), msg, refname,
- old_oid, flags);
-}
-
static void copy_reflog_msg(struct strbuf *sb, const char *msg)
{
char c;
return tr;
}
-struct ref_transaction *ref_transaction_begin(struct strbuf *err)
-{
- return ref_store_transaction_begin(get_main_ref_store(the_repository), err);
-}
-
void ref_transaction_free(struct ref_transaction *transaction)
{
size_t i;
for (i = 0; i < transaction->nr; i++) {
free(transaction->updates[i]->msg);
+ free((char *)transaction->updates[i]->new_target);
+ free((char *)transaction->updates[i]->old_target);
free(transaction->updates[i]);
}
free(transaction->updates);
const char *refname, unsigned int flags,
const struct object_id *new_oid,
const struct object_id *old_oid,
+ const char *new_target, const char *old_target,
const char *msg)
{
struct ref_update *update;
if (transaction->state != REF_TRANSACTION_OPEN)
BUG("update called for transaction that is not open");
+ if (old_oid && old_target)
+ BUG("only one of old_oid and old_target should be non NULL");
+ if (new_oid && new_target)
+ BUG("only one of new_oid and new_target should be non NULL");
+
FLEX_ALLOC_STR(update, refname, refname);
ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
transaction->updates[transaction->nr++] = update;
update->flags = flags;
- if (flags & REF_HAVE_NEW)
+ update->new_target = xstrdup_or_null(new_target);
+ update->old_target = xstrdup_or_null(old_target);
+ if ((flags & REF_HAVE_NEW) && new_oid)
oidcpy(&update->new_oid, new_oid);
- if (flags & REF_HAVE_OLD)
+ if ((flags & REF_HAVE_OLD) && old_oid)
oidcpy(&update->old_oid, old_oid);
+
update->msg = normalize_reflog_message(msg);
return update;
}
const char *refname,
const struct object_id *new_oid,
const struct object_id *old_oid,
+ const char *new_target,
+ const char *old_target,
unsigned int flags, const char *msg,
struct strbuf *err)
{
flags &= REF_TRANSACTION_UPDATE_ALLOWED_FLAGS;
flags |= (new_oid ? REF_HAVE_NEW : 0) | (old_oid ? REF_HAVE_OLD : 0);
+ flags |= (new_target ? REF_HAVE_NEW : 0) | (old_target ? REF_HAVE_OLD : 0);
ref_transaction_add_update(transaction, refname, flags,
- new_oid, old_oid, msg);
+ new_oid, old_oid, new_target,
+ old_target, msg);
return 0;
}
return 1;
}
return ref_transaction_update(transaction, refname, new_oid,
- null_oid(), flags, msg, err);
+ null_oid(), NULL, NULL, flags,
+ msg, err);
}
int ref_transaction_delete(struct ref_transaction *transaction,
BUG("delete called with old_oid set to zeros");
return ref_transaction_update(transaction, refname,
null_oid(), old_oid,
- flags, msg, err);
+ NULL, NULL, flags,
+ msg, err);
}
int ref_transaction_verify(struct ref_transaction *transaction,
BUG("verify called with old_oid set to NULL");
return ref_transaction_update(transaction, refname,
NULL, old_oid,
+ NULL, NULL,
flags, NULL, err);
}
t = ref_store_transaction_begin(refs, &err);
if (!t ||
- ref_transaction_update(t, refname, new_oid, old_oid, flags, msg,
- &err) ||
+ ref_transaction_update(t, refname, new_oid, old_oid, NULL, NULL,
+ flags, msg, &err) ||
ref_transaction_commit(t, &err)) {
ret = 1;
ref_transaction_free(t);
return 0;
}
-int update_ref(const char *msg, const char *refname,
- const struct object_id *new_oid,
- const struct object_id *old_oid,
- unsigned int flags, enum action_on_err onerr)
-{
- return refs_update_ref(get_main_ref_store(the_repository), msg, refname, new_oid,
- old_oid, flags, onerr);
-}
-
/*
* Check that the string refname matches a rule of the form
* "{prefix}%.*s{suffix}". So "foo/bar/baz" would match the rule
return xstrdup(refname);
}
-char *shorten_unambiguous_ref(const char *refname, int strict)
-{
- return refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
- refname, strict);
-}
-
int parse_hide_refs_config(const char *var, const char *value, const char *section,
struct strvec *hide_refs)
{
return 0;
}
-int head_ref(each_ref_fn fn, void *cb_data)
-{
- return refs_head_ref(get_main_ref_store(the_repository), fn, cb_data);
-}
-
struct ref_iterator *refs_ref_iterator_begin(
struct ref_store *refs,
const char *prefix,
return do_for_each_ref(refs, "", NULL, fn, 0, 0, cb_data);
}
-int for_each_ref(each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_ref(get_main_ref_store(the_repository), fn, cb_data);
-}
-
int refs_for_each_ref_in(struct ref_store *refs, const char *prefix,
each_ref_fn fn, void *cb_data)
{
return do_for_each_ref(refs, prefix, NULL, fn, strlen(prefix), 0, cb_data);
}
-int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_ref_in(get_main_ref_store(the_repository), prefix, fn, cb_data);
-}
-
-int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data)
-{
- return do_for_each_ref(get_main_ref_store(the_repository),
- prefix, NULL, fn, 0, 0, cb_data);
-}
-
int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix,
const char **exclude_patterns,
each_ref_fn fn, void *cb_data)
DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
}
-int for_each_namespaced_ref(const char **exclude_patterns,
- each_ref_fn fn, void *cb_data)
+int refs_for_each_namespaced_ref(struct ref_store *refs,
+ const char **exclude_patterns,
+ each_ref_fn fn, void *cb_data)
{
struct strbuf buf = STRBUF_INIT;
int ret;
strbuf_addf(&buf, "%srefs/", get_git_namespace());
- ret = do_for_each_ref(get_main_ref_store(the_repository),
- buf.buf, exclude_patterns, fn, 0, 0, cb_data);
+ ret = do_for_each_ref(refs, buf.buf, exclude_patterns, fn, 0, 0, cb_data);
strbuf_release(&buf);
return ret;
}
DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
}
-int for_each_rawref(each_ref_fn fn, void *cb_data)
-{
- return refs_for_each_rawref(get_main_ref_store(the_repository), fn, cb_data);
-}
-
int refs_for_each_include_root_refs(struct ref_store *refs, each_ref_fn fn,
void *cb_data)
{
return refs->be->init_db(refs, flags, err);
}
-const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
- struct object_id *oid, int *flags)
-{
- return refs_resolve_ref_unsafe(get_main_ref_store(the_repository), refname,
- resolve_flags, oid, flags);
-}
-
int resolve_gitlink_ref(const char *submodule, const char *refname,
struct object_id *oid)
{
return peel_object(base, peeled) ? -1 : 0;
}
-int refs_create_symref(struct ref_store *refs,
- const char *ref_target,
- const char *refs_heads_master,
- const char *logmsg)
+int refs_update_symref(struct ref_store *refs, const char *ref,
+ const char *target, const char *logmsg)
{
- char *msg;
- int retval;
+ struct ref_transaction *transaction;
+ struct strbuf err = STRBUF_INIT;
+ int ret = 0;
- msg = normalize_reflog_message(logmsg);
- retval = refs->be->create_symref(refs, ref_target, refs_heads_master,
- msg);
- free(msg);
- return retval;
-}
+ transaction = ref_store_transaction_begin(refs, &err);
+ if (!transaction ||
+ ref_transaction_update(transaction, ref, NULL, NULL,
+ target, NULL, REF_NO_DEREF,
+ logmsg, &err) ||
+ ref_transaction_commit(transaction, &err)) {
+ ret = error("%s", err.buf);
+ }
-int create_symref(const char *ref_target, const char *refs_heads_master,
- const char *logmsg)
-{
- return refs_create_symref(get_main_ref_store(the_repository), ref_target,
- refs_heads_master, logmsg);
+ strbuf_release(&err);
+ if (transaction)
+ ref_transaction_free(transaction);
+
+ return ret;
}
int ref_update_reject_duplicates(struct string_list *refnames,
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 (!(update->flags & REF_HAVE_OLD))
+ strbuf_addf(&buf, "%s ", oid_to_hex(null_oid()));
+ else if (update->old_target)
+ strbuf_addf(&buf, "ref:%s ", update->old_target);
+ else
+ strbuf_addf(&buf, "%s ", oid_to_hex(&update->old_oid));
+
+ if (!(update->flags & REF_HAVE_NEW))
+ strbuf_addf(&buf, "%s ", oid_to_hex(null_oid()));
+ else if (update->new_target)
+ strbuf_addf(&buf, "ref:%s ", update->new_target);
+ else
+ strbuf_addf(&buf, "%s ", oid_to_hex(&update->new_oid));
+
+ strbuf_addf(&buf, "%s\n", update->refname);
if (write_in_full(proc.in, buf.buf, buf.len) < 0) {
if (errno != EPIPE) {
do_for_each_reflog_helper, &hp);
}
-int for_each_reflog(each_reflog_fn fn, void *cb_data)
-{
- return refs_for_each_reflog(get_main_ref_store(the_repository), fn, cb_data);
-}
-
int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
const char *refname,
each_reflog_ent_fn fn,
fn, cb_data);
}
-int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
- void *cb_data)
-{
- return refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository),
- refname, fn, cb_data);
-}
-
int refs_for_each_reflog_ent(struct ref_store *refs, const char *refname,
each_reflog_ent_fn fn, void *cb_data)
{
return refs->be->for_each_reflog_ent(refs, refname, fn, cb_data);
}
-int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
- void *cb_data)
-{
- return refs_for_each_reflog_ent(get_main_ref_store(the_repository), refname,
- fn, cb_data);
-}
-
int refs_reflog_exists(struct ref_store *refs, const char *refname)
{
return refs->be->reflog_exists(refs, refname);
}
-int reflog_exists(const char *refname)
-{
- return refs_reflog_exists(get_main_ref_store(the_repository), refname);
-}
-
int refs_create_reflog(struct ref_store *refs, const char *refname,
struct strbuf *err)
{
return refs->be->create_reflog(refs, refname, err);
}
-int safe_create_reflog(const char *refname, struct strbuf *err)
-{
- return refs_create_reflog(get_main_ref_store(the_repository), refname,
- err);
-}
-
int refs_delete_reflog(struct ref_store *refs, const char *refname)
{
return refs->be->delete_reflog(refs, refname);
}
-int delete_reflog(const char *refname)
-{
- return refs_delete_reflog(get_main_ref_store(the_repository), refname);
-}
-
int refs_reflog_expire(struct ref_store *refs,
const char *refname,
unsigned int flags,
cleanup_fn, policy_cb_data);
}
-int reflog_expire(const char *refname,
- unsigned int flags,
- reflog_expiry_prepare_fn prepare_fn,
- reflog_expiry_should_prune_fn should_prune_fn,
- reflog_expiry_cleanup_fn cleanup_fn,
- void *policy_cb_data)
-{
- return refs_reflog_expire(get_main_ref_store(the_repository),
- refname, flags,
- prepare_fn, should_prune_fn,
- cleanup_fn, policy_cb_data);
-}
-
int initial_ref_transaction_commit(struct ref_transaction *transaction,
struct strbuf *err)
{
return ret;
}
-int delete_refs(const char *msg, struct string_list *refnames,
- unsigned int flags)
-{
- return refs_delete_refs(get_main_ref_store(the_repository), msg, refnames, flags);
-}
-
int refs_rename_ref(struct ref_store *refs, const char *oldref,
const char *newref, const char *logmsg)
{
return retval;
}
-int rename_ref(const char *oldref, const char *newref, const char *logmsg)
-{
- return refs_rename_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
-}
-
int refs_copy_existing_ref(struct ref_store *refs, const char *oldref,
const char *newref, const char *logmsg)
{
return retval;
}
-int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg)
+const char *ref_update_original_update_refname(struct ref_update *update)
+{
+ while (update->parent_update)
+ update = update->parent_update;
+
+ return update->refname;
+}
+
+int ref_update_has_null_new_value(struct ref_update *update)
+{
+ return !update->new_target && is_null_oid(&update->new_oid);
+}
+
+int ref_update_check_old_target(const char *referent, struct ref_update *update,
+ struct strbuf *err)
{
- return refs_copy_existing_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
+ if (!update->old_target)
+ BUG("called without old_target set");
+
+ if (!strcmp(referent, update->old_target))
+ return 0;
+
+ if (!strcmp(referent, ""))
+ strbuf_addf(err, "verifying symref target: '%s': "
+ "reference is missing but expected %s",
+ ref_update_original_update_refname(update),
+ update->old_target);
+ else
+ strbuf_addf(err, "verifying symref target: '%s': "
+ "is at %s but expected %s",
+ ref_update_original_update_refname(update),
+ referent, update->old_target);
+ return -1;
}