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>

Patrick Steinhardt committed Nov 14, 2023 at 09:58 UTC d6f8e7298254d8291724f9f57648b3ab5f8d3770
3 files changed +47 -92
refs.c
+45 -3
@@ -2599,13 +2599,55 @@ void ref_transaction_for_each_queued_update(struct ref_transaction *transaction,
2599 int refs_delete_refs(struct ref_store *refs, const char *logmsg,
2600 struct string_list *refnames, unsigned int flags)
2601 {
2602 + struct ref_transaction *transaction;
2603 + struct strbuf err = STRBUF_INIT;
2604 + struct string_list_item *item;
2605 + int ret = 0, failures = 0;
2606 char *msg;
2603 - int retval;
2607 +
2608 + if (!refnames->nr)
2609 + return 0;
2610
2611 msg = normalize_reflog_message(logmsg);
2606 - retval = refs->be->delete_refs(refs, msg, refnames, flags);
2612 +
2613 + /*
2614 + * Since we don't check the references' old_oids, the
2615 + * individual updates can't fail, so we can pack all of the
2616 + * updates into a single transaction.
2617 + */
2618 + transaction = ref_store_transaction_begin(refs, &err);
2619 + if (!transaction) {
2620 + ret = error("%s", err.buf);
2621 + goto out;
2622 + }
2623 +
2624 + for_each_string_list_item(item, refnames) {
2625 + ret = ref_transaction_delete(transaction, item->string,
2626 + NULL, flags, msg, &err);
2627 + if (ret) {
2628 + warning(_("could not delete reference %s: %s"),
2629 + item->string, err.buf);
2630 + strbuf_reset(&err);
2631 + failures = 1;
2632 + }
2633 + }
2634 +
2635 + ret = ref_transaction_commit(transaction, &err);
2636 + if (ret) {
2637 + if (refnames->nr == 1)
2638 + error(_("could not delete reference %s: %s"),
2639 + refnames->items[0].string, err.buf);
2640 + else
2641 + error(_("could not delete references: %s"), err.buf);
2642 + }
2643 +
2644 +out:
2645 + if (!ret && failures)
2646 + ret = -1;
2647 + ref_transaction_free(transaction);
2648 + strbuf_release(&err);
2649 free(msg);
2608 - return retval;
2650 + return ret;
2651 }
2652
2653 int delete_refs(const char *msg, struct string_list *refnames,
refs/files-backend.c
+1 -45
@@ -1268,51 +1268,7 @@ static int files_pack_refs(struct ref_store *ref_store,
1268 static int files_delete_refs(struct ref_store *ref_store, const char *msg,
1269 struct string_list *refnames, unsigned int flags)
1270 {
1271 - struct ref_transaction *transaction;
1272 - struct strbuf err = STRBUF_INIT;
1273 - struct string_list_item *item;
1274 - int ret = 0, failures = 0;
1275 -
1276 - if (!refnames->nr)
1277 - return 0;
1278 -
1279 - /*
1280 - * Since we don't check the references' old_oids, the
1281 - * individual updates can't fail, so we can pack all of the
1282 - * updates into a single transaction.
1283 - */
1284 - transaction = ref_store_transaction_begin(ref_store, &err);
1285 - if (!transaction) {
1286 - ret = error("%s", err.buf);
1287 - goto out;
1288 - }
1289 -
1290 - for_each_string_list_item(item, refnames) {
1291 - ret = ref_transaction_delete(transaction, item->string,
1292 - NULL, flags, msg, &err);
1293 - if (ret) {
1294 - warning(_("could not delete reference %s: %s"),
1295 - item->string, err.buf);
1296 - strbuf_reset(&err);
1297 - failures = 1;
1298 - }
1299 - }
1300 -
1301 - ret = ref_transaction_commit(transaction, &err);
1302 - if (ret) {
1303 - if (refnames->nr == 1)
1304 - error(_("could not delete reference %s: %s"),
1305 - refnames->items[0].string, err.buf);
1306 - else
1307 - error(_("could not delete references: %s"), err.buf);
1308 - }
1309 -
1310 -out:
1311 - if (!ret && failures)
1312 - ret = -1;
1313 - ref_transaction_free(transaction);
1314 - strbuf_release(&err);
1315 - return ret;
1271 + return refs_delete_refs(ref_store, msg, refnames, flags);
1272 }
1273
1274 /*
refs/packed-backend.c
+1 -44
@@ -1691,50 +1691,7 @@ static int packed_initial_transaction_commit(struct ref_store *ref_store UNUSED,
1691 static int packed_delete_refs(struct ref_store *ref_store, const char *msg,
1692 struct string_list *refnames, unsigned int flags)
1693 {
1694 - struct packed_ref_store *refs =
1695 - packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs");
1696 - struct strbuf err = STRBUF_INIT;
1697 - struct ref_transaction *transaction;
1698 - struct string_list_item *item;
1699 - int ret;
1700 -
1701 - (void)refs; /* We need the check above, but don't use the variable */
1702 -
1703 - if (!refnames->nr)
1704 - return 0;
1705 -
1706 - /*
1707 - * Since we don't check the references' old_oids, the
1708 - * individual updates can't fail, so we can pack all of the
1709 - * updates into a single transaction.
1710 - */
1711 -
1712 - transaction = ref_store_transaction_begin(ref_store, &err);
1713 - if (!transaction)
1714 - return -1;
1715 -
1716 - for_each_string_list_item(item, refnames) {
1717 - if (ref_transaction_delete(transaction, item->string, NULL,
1718 - flags, msg, &err)) {
1719 - warning(_("could not delete reference %s: %s"),
1720 - item->string, err.buf);
1721 - strbuf_reset(&err);
1722 - }
1723 - }
1724 -
1725 - ret = ref_transaction_commit(transaction, &err);
1726 -
1727 - if (ret) {
1728 - if (refnames->nr == 1)
1729 - error(_("could not delete reference %s: %s"),
1730 - refnames->items[0].string, err.buf);
1731 - else
1732 - error(_("could not delete references: %s"), err.buf);
1733 - }
1734 -
1735 - ref_transaction_free(transaction);
1736 - strbuf_release(&err);
1737 - return ret;
1694 + return refs_delete_refs(ref_store, msg, refnames, flags);
1695 }
1696
1697 static int packed_pack_refs(struct ref_store *ref_store UNUSED,