refs: extract packed_refs_delete_refs() to allow control of transaction
When deleting loose refs, then we also have to delete the refs in the packed backend. This is done by calling `refs_delete_refs()`, which then uses the packed-backend's logic to delete refs. This doesn't allow us to exercise any control over the reference transaction which is being created in the packed backend, which is required in a subsequent commit. Extract a new function `packed_refs_delete_refs()`, which hosts most of the logic to delete refs except for creating the transaction itself. Like this, we can easily create the transaction in the files backend and thus exert more control over it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Jan 17, 2022 at 09:12 UTC
69840cc0f7b4f3352903bd2b8f3de7077916c26b
3 files changed
+37
-9
refs/files-backend.c
+10
-3
@@ -1249,6 +1249,7 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg,
1249
{
1250
struct files_ref_store *refs =
1251
files_downcast(ref_store, REF_STORE_WRITE, "delete_refs");
1252
+ struct ref_transaction *transaction = NULL;
1253
struct strbuf err = STRBUF_INIT;
1254
int i, result = 0;
1255
@@ -1258,10 +1259,14 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg,
1259
if (packed_refs_lock(refs->packed_ref_store, 0, &err))
1260
goto error;
1261
1261
- if (refs_delete_refs(refs->packed_ref_store, msg, refnames, flags)) {
1262
- packed_refs_unlock(refs->packed_ref_store);
1262
+ transaction = ref_store_transaction_begin(refs->packed_ref_store, &err);
1263
+ if (!transaction)
1264
+ goto error;
1265
+
1266
+ result = packed_refs_delete_refs(refs->packed_ref_store,
1267
+ transaction, msg, refnames, flags);
1268
+ if (result)
1269
goto error;
1264
- }
1270
1271
packed_refs_unlock(refs->packed_ref_store);
1272
@@ -1272,6 +1277,7 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg,
1277
result |= error(_("could not remove reference %s"), refname);
1278
}
1279
1280
+ ref_transaction_free(transaction);
1281
strbuf_release(&err);
1282
return result;
1283
@@ -1288,6 +1294,7 @@ error:
1294
else
1295
error(_("could not delete references: %s"), err.buf);
1296
1297
+ ref_transaction_free(transaction);
1298
strbuf_release(&err);
1299
return -1;
1300
}
refs/packed-backend.c
+20
-6
@@ -1522,15 +1522,10 @@ static int packed_initial_transaction_commit(struct ref_store *ref_store,
1522
static int packed_delete_refs(struct ref_store *ref_store, const char *msg,
1523
struct string_list *refnames, unsigned int flags)
1524
{
1525
- struct packed_ref_store *refs =
1526
- packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs");
1525
struct strbuf err = STRBUF_INIT;
1526
struct ref_transaction *transaction;
1529
- struct string_list_item *item;
1527
int ret;
1528
1532
- (void)refs; /* We need the check above, but don't use the variable */
1533
-
1529
if (!refnames->nr)
1530
return 0;
1531
@@ -1544,6 +1539,26 @@ static int packed_delete_refs(struct ref_store *ref_store, const char *msg,
1539
if (!transaction)
1540
return -1;
1541
1542
+ ret = packed_refs_delete_refs(ref_store, transaction,
1543
+ msg, refnames, flags);
1544
+
1545
+ ref_transaction_free(transaction);
1546
+ return ret;
1547
+}
1548
+
1549
+int packed_refs_delete_refs(struct ref_store *ref_store,
1550
+ struct ref_transaction *transaction,
1551
+ const char *msg,
1552
+ struct string_list *refnames,
1553
+ unsigned int flags)
1554
+{
1555
+ struct strbuf err = STRBUF_INIT;
1556
+ struct string_list_item *item;
1557
+ int ret;
1558
+
1559
+ /* Assert that the ref store refers to a packed backend. */
1560
+ packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs");
1561
+
1562
for_each_string_list_item(item, refnames) {
1563
if (ref_transaction_delete(transaction, item->string, NULL,
1564
flags, msg, &err)) {
@@ -1563,7 +1578,6 @@ static int packed_delete_refs(struct ref_store *ref_store, const char *msg,
1578
error(_("could not delete references: %s"), err.buf);
1579
}
1580
1566
- ref_transaction_free(transaction);
1581
strbuf_release(&err);
1582
return ret;
1583
}
refs/packed-backend.h
+7
@@ -3,6 +3,7 @@
3
4
struct repository;
5
struct ref_transaction;
6
+struct string_list;
7
8
/*
9
* Support for storing references in a `packed-refs` file.
@@ -27,6 +28,12 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err)
28
void packed_refs_unlock(struct ref_store *ref_store);
29
int packed_refs_is_locked(struct ref_store *ref_store);
30
31
+int packed_refs_delete_refs(struct ref_store *ref_store,
32
+ struct ref_transaction *transaction,
33
+ const char *msg,
34
+ struct string_list *refnames,
35
+ unsigned int flags);
36
+
37
/*
38
* Return true if `transaction` really needs to be carried out against
39
* the specified packed_ref_store, or false if it can be skipped