Skip to content

Commit 71c7466

Browse files
committed
Merge branch 'ps/ref-deletion-updates'
Simplify API implementation to delete references by eliminating duplication. * ps/ref-deletion-updates: refs: remove `delete_refs` callback from backends refs: deduplicate code to delete references refs/files: use transactions to delete references t5510: ensure that the packed-refs file needs locking
2 parents f1c5377 + 29a1869 commit 71c7466

File tree

6 files changed

+46
-120
lines changed

6 files changed

+46
-120
lines changed

refs.c

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,13 +2599,55 @@ void ref_transaction_for_each_queued_update(struct ref_transaction *transaction,
25992599
int refs_delete_refs(struct ref_store *refs, const char *logmsg,
26002600
struct string_list *refnames, unsigned int flags)
26012601
{
2602+
struct ref_transaction *transaction;
2603+
struct strbuf err = STRBUF_INIT;
2604+
struct string_list_item *item;
2605+
int ret = 0, failures = 0;
26022606
char *msg;
2603-
int retval;
2607+
2608+
if (!refnames->nr)
2609+
return 0;
26042610

26052611
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);
26072649
free(msg);
2608-
return retval;
2650+
return ret;
26092651
}
26102652

26112653
int delete_refs(const char *msg, struct string_list *refnames,

refs/debug.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -143,20 +143,6 @@ static int debug_create_symref(struct ref_store *ref_store,
143143
return res;
144144
}
145145

146-
static int debug_delete_refs(struct ref_store *ref_store, const char *msg,
147-
struct string_list *refnames, unsigned int flags)
148-
{
149-
struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
150-
int res =
151-
drefs->refs->be->delete_refs(drefs->refs, msg, refnames, flags);
152-
int i;
153-
trace_printf_key(&trace_refs, "delete_refs {\n");
154-
for (i = 0; i < refnames->nr; i++)
155-
trace_printf_key(&trace_refs, "%s\n", refnames->items[i].string);
156-
trace_printf_key(&trace_refs, "}: %d\n", res);
157-
return res;
158-
}
159-
160146
static int debug_rename_ref(struct ref_store *ref_store, const char *oldref,
161147
const char *newref, const char *logmsg)
162148
{
@@ -458,7 +444,6 @@ struct ref_storage_be refs_be_debug = {
458444

459445
.pack_refs = debug_pack_refs,
460446
.create_symref = debug_create_symref,
461-
.delete_refs = debug_delete_refs,
462447
.rename_ref = debug_rename_ref,
463448
.copy_ref = debug_copy_ref,
464449

refs/files-backend.c

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,54 +1265,6 @@ static int files_pack_refs(struct ref_store *ref_store,
12651265
return 0;
12661266
}
12671267

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 files_ref_store *refs =
1272-
files_downcast(ref_store, REF_STORE_WRITE, "delete_refs");
1273-
struct strbuf err = STRBUF_INIT;
1274-
int i, result = 0;
1275-
1276-
if (!refnames->nr)
1277-
return 0;
1278-
1279-
if (packed_refs_lock(refs->packed_ref_store, 0, &err))
1280-
goto error;
1281-
1282-
if (refs_delete_refs(refs->packed_ref_store, msg, refnames, flags)) {
1283-
packed_refs_unlock(refs->packed_ref_store);
1284-
goto error;
1285-
}
1286-
1287-
packed_refs_unlock(refs->packed_ref_store);
1288-
1289-
for (i = 0; i < refnames->nr; i++) {
1290-
const char *refname = refnames->items[i].string;
1291-
1292-
if (refs_delete_ref(&refs->base, msg, refname, NULL, flags))
1293-
result |= error(_("could not remove reference %s"), refname);
1294-
}
1295-
1296-
strbuf_release(&err);
1297-
return result;
1298-
1299-
error:
1300-
/*
1301-
* If we failed to rewrite the packed-refs file, then it is
1302-
* unsafe to try to remove loose refs, because doing so might
1303-
* expose an obsolete packed value for a reference that might
1304-
* even point at an object that has been garbage collected.
1305-
*/
1306-
if (refnames->nr == 1)
1307-
error(_("could not delete reference %s: %s"),
1308-
refnames->items[0].string, err.buf);
1309-
else
1310-
error(_("could not delete references: %s"), err.buf);
1311-
1312-
strbuf_release(&err);
1313-
return -1;
1314-
}
1315-
13161268
/*
13171269
* People using contrib's git-new-workdir have .git/logs/refs ->
13181270
* /some/other/path/.git/logs/refs, and that may live on another device.
@@ -3300,7 +3252,6 @@ struct ref_storage_be refs_be_files = {
33003252

33013253
.pack_refs = files_pack_refs,
33023254
.create_symref = files_create_symref,
3303-
.delete_refs = files_delete_refs,
33043255
.rename_ref = files_rename_ref,
33053256
.copy_ref = files_copy_ref,
33063257

refs/packed-backend.c

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,55 +1688,6 @@ static int packed_initial_transaction_commit(struct ref_store *ref_store UNUSED,
16881688
return ref_transaction_commit(transaction, err);
16891689
}
16901690

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;
1738-
}
1739-
17401691
static int packed_pack_refs(struct ref_store *ref_store UNUSED,
17411692
struct pack_refs_opts *pack_opts UNUSED)
17421693
{
@@ -1765,7 +1716,6 @@ struct ref_storage_be refs_be_packed = {
17651716

17661717
.pack_refs = packed_pack_refs,
17671718
.create_symref = NULL,
1768-
.delete_refs = packed_delete_refs,
17691719
.rename_ref = NULL,
17701720
.copy_ref = NULL,
17711721

refs/refs-internal.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -553,8 +553,6 @@ typedef int create_symref_fn(struct ref_store *ref_store,
553553
const char *ref_target,
554554
const char *refs_heads_master,
555555
const char *logmsg);
556-
typedef int delete_refs_fn(struct ref_store *ref_store, const char *msg,
557-
struct string_list *refnames, unsigned int flags);
558556
typedef int rename_ref_fn(struct ref_store *ref_store,
559557
const char *oldref, const char *newref,
560558
const char *logmsg);
@@ -677,7 +675,6 @@ struct ref_storage_be {
677675

678676
pack_refs_fn *pack_refs;
679677
create_symref_fn *create_symref;
680-
delete_refs_fn *delete_refs;
681678
rename_ref_fn *rename_ref;
682679
copy_ref_fn *copy_ref;
683680

t/t5510-fetch.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ test_expect_success REFFILES 'fetch --prune fails to delete branches' '
169169
git clone . prune-fail &&
170170
cd prune-fail &&
171171
git update-ref refs/remotes/origin/extrabranch main &&
172+
git pack-refs --all &&
172173
: this will prevent --prune from locking packed-refs for deleting refs, but adding loose refs still succeeds &&
173174
>.git/packed-refs.new &&
174175

0 commit comments

Comments
 (0)