refs: deduplicate code to delete references
Both the files and the packed-refs reference backends now use the same generic transactions-based code to delete references. Let's pull these implementations up into `refs_delete_refs()` to deduplicate the code. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
e85e5dd78a
commit
d6f8e72982
48
refs.c
48
refs.c
@ -2599,13 +2599,55 @@ void ref_transaction_for_each_queued_update(struct ref_transaction *transaction,
|
|||||||
int refs_delete_refs(struct ref_store *refs, const char *logmsg,
|
int refs_delete_refs(struct ref_store *refs, const char *logmsg,
|
||||||
struct string_list *refnames, unsigned int flags)
|
struct string_list *refnames, unsigned int flags)
|
||||||
{
|
{
|
||||||
|
struct ref_transaction *transaction;
|
||||||
|
struct strbuf err = STRBUF_INIT;
|
||||||
|
struct string_list_item *item;
|
||||||
|
int ret = 0, failures = 0;
|
||||||
char *msg;
|
char *msg;
|
||||||
int retval;
|
|
||||||
|
if (!refnames->nr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
msg = normalize_reflog_message(logmsg);
|
msg = normalize_reflog_message(logmsg);
|
||||||
retval = refs->be->delete_refs(refs, msg, refnames, flags);
|
|
||||||
|
/*
|
||||||
|
* Since we don't check the references' old_oids, the
|
||||||
|
* individual updates can't fail, so we can pack all of the
|
||||||
|
* updates into a single transaction.
|
||||||
|
*/
|
||||||
|
transaction = ref_store_transaction_begin(refs, &err);
|
||||||
|
if (!transaction) {
|
||||||
|
ret = error("%s", err.buf);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each_string_list_item(item, refnames) {
|
||||||
|
ret = ref_transaction_delete(transaction, item->string,
|
||||||
|
NULL, flags, msg, &err);
|
||||||
|
if (ret) {
|
||||||
|
warning(_("could not delete reference %s: %s"),
|
||||||
|
item->string, err.buf);
|
||||||
|
strbuf_reset(&err);
|
||||||
|
failures = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ref_transaction_commit(transaction, &err);
|
||||||
|
if (ret) {
|
||||||
|
if (refnames->nr == 1)
|
||||||
|
error(_("could not delete reference %s: %s"),
|
||||||
|
refnames->items[0].string, err.buf);
|
||||||
|
else
|
||||||
|
error(_("could not delete references: %s"), err.buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (!ret && failures)
|
||||||
|
ret = -1;
|
||||||
|
ref_transaction_free(transaction);
|
||||||
|
strbuf_release(&err);
|
||||||
free(msg);
|
free(msg);
|
||||||
return retval;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int delete_refs(const char *msg, struct string_list *refnames,
|
int delete_refs(const char *msg, struct string_list *refnames,
|
||||||
|
@ -1268,51 +1268,7 @@ static int files_pack_refs(struct ref_store *ref_store,
|
|||||||
static int files_delete_refs(struct ref_store *ref_store, const char *msg,
|
static int files_delete_refs(struct ref_store *ref_store, const char *msg,
|
||||||
struct string_list *refnames, unsigned int flags)
|
struct string_list *refnames, unsigned int flags)
|
||||||
{
|
{
|
||||||
struct ref_transaction *transaction;
|
return refs_delete_refs(ref_store, msg, refnames, flags);
|
||||||
struct strbuf err = STRBUF_INIT;
|
|
||||||
struct string_list_item *item;
|
|
||||||
int ret = 0, failures = 0;
|
|
||||||
|
|
||||||
if (!refnames->nr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Since we don't check the references' old_oids, the
|
|
||||||
* individual updates can't fail, so we can pack all of the
|
|
||||||
* updates into a single transaction.
|
|
||||||
*/
|
|
||||||
transaction = ref_store_transaction_begin(ref_store, &err);
|
|
||||||
if (!transaction) {
|
|
||||||
ret = error("%s", err.buf);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
for_each_string_list_item(item, refnames) {
|
|
||||||
ret = ref_transaction_delete(transaction, item->string,
|
|
||||||
NULL, flags, msg, &err);
|
|
||||||
if (ret) {
|
|
||||||
warning(_("could not delete reference %s: %s"),
|
|
||||||
item->string, err.buf);
|
|
||||||
strbuf_reset(&err);
|
|
||||||
failures = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ref_transaction_commit(transaction, &err);
|
|
||||||
if (ret) {
|
|
||||||
if (refnames->nr == 1)
|
|
||||||
error(_("could not delete reference %s: %s"),
|
|
||||||
refnames->items[0].string, err.buf);
|
|
||||||
else
|
|
||||||
error(_("could not delete references: %s"), err.buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (!ret && failures)
|
|
||||||
ret = -1;
|
|
||||||
ref_transaction_free(transaction);
|
|
||||||
strbuf_release(&err);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1691,50 +1691,7 @@ static int packed_initial_transaction_commit(struct ref_store *ref_store UNUSED,
|
|||||||
static int packed_delete_refs(struct ref_store *ref_store, const char *msg,
|
static int packed_delete_refs(struct ref_store *ref_store, const char *msg,
|
||||||
struct string_list *refnames, unsigned int flags)
|
struct string_list *refnames, unsigned int flags)
|
||||||
{
|
{
|
||||||
struct packed_ref_store *refs =
|
return refs_delete_refs(ref_store, msg, refnames, flags);
|
||||||
packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs");
|
|
||||||
struct strbuf err = STRBUF_INIT;
|
|
||||||
struct ref_transaction *transaction;
|
|
||||||
struct string_list_item *item;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
(void)refs; /* We need the check above, but don't use the variable */
|
|
||||||
|
|
||||||
if (!refnames->nr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Since we don't check the references' old_oids, the
|
|
||||||
* individual updates can't fail, so we can pack all of the
|
|
||||||
* updates into a single transaction.
|
|
||||||
*/
|
|
||||||
|
|
||||||
transaction = ref_store_transaction_begin(ref_store, &err);
|
|
||||||
if (!transaction)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
for_each_string_list_item(item, refnames) {
|
|
||||||
if (ref_transaction_delete(transaction, item->string, NULL,
|
|
||||||
flags, msg, &err)) {
|
|
||||||
warning(_("could not delete reference %s: %s"),
|
|
||||||
item->string, err.buf);
|
|
||||||
strbuf_reset(&err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ref_transaction_commit(transaction, &err);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
if (refnames->nr == 1)
|
|
||||||
error(_("could not delete reference %s: %s"),
|
|
||||||
refnames->items[0].string, err.buf);
|
|
||||||
else
|
|
||||||
error(_("could not delete references: %s"), err.buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
ref_transaction_free(transaction);
|
|
||||||
strbuf_release(&err);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int packed_pack_refs(struct ref_store *ref_store UNUSED,
|
static int packed_pack_refs(struct ref_store *ref_store UNUSED,
|
||||||
|
Reference in New Issue
Block a user