On Thu, Jan 13, 2022 at 01:43:18PM +0100, Ævar Arnfjörð Bjarmason wrote: > > On Thu, Jan 13 2022, Patrick Steinhardt wrote: > > > [[PGP Signed Part:Undecided]] > > 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 > > --- > > refs/files-backend.c | 12 +++++++++--- > > refs/packed-backend.c | 28 +++++++++++++++++++++------- > > refs/packed-backend.h | 7 +++++++ > > 3 files changed, 37 insertions(+), 10 deletions(-) > > > > diff --git a/refs/files-backend.c b/refs/files-backend.c > > index 90b671025a..5795e54020 100644 > > --- a/refs/files-backend.c > > +++ b/refs/files-backend.c > > @@ -1249,6 +1249,7 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg, > > { > > struct files_ref_store *refs = > > files_downcast(ref_store, REF_STORE_WRITE, "delete_refs"); > > + struct ref_transaction *transaction = NULL; > > nit: "NULL initialization never needed? > (re: https://lore.kernel.org/git/220113.86bl0gvtq3.gmgdl@evledraar.gmail.com/) It is needed: if locking the packed-refs file fails we `goto error;` and try to free the transaction without it having been initialized yet. > > struct strbuf err = STRBUF_INIT; > > int i, result = 0; > > > > @@ -1258,10 +1259,14 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg, > > if (packed_refs_lock(refs->packed_ref_store, 0, &err)) > > goto error; > > > > - if (refs_delete_refs(refs->packed_ref_store, msg, refnames, flags)) { > > - packed_refs_unlock(refs->packed_ref_store); > > + transaction = ref_store_transaction_begin(refs->packed_ref_store, &err); > > + if (!transaction) > > + goto error; > > + > > + result = packed_refs_delete_refs(refs->packed_ref_store, > > + transaction, msg, refnames, flags); > > + if (result) > > goto error; > > - } > > > > packed_refs_unlock(refs->packed_ref_store); > > > > @@ -1288,6 +1293,7 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg, > > else > > error(_("could not delete references: %s"), err.buf); > > > > + ref_transaction_free(transaction); > > strbuf_release(&err); > > return -1; > > } > > diff --git a/refs/packed-backend.c b/refs/packed-backend.c > > index 67152c664e..e97d67f932 100644 > > --- a/refs/packed-backend.c > > +++ b/refs/packed-backend.c > > @@ -1522,15 +1522,10 @@ static int packed_initial_transaction_commit(struct ref_store *ref_store, > > static int packed_delete_refs(struct ref_store *ref_store, const char *msg, > > struct string_list *refnames, unsigned int flags) > > { > > - struct packed_ref_store *refs = > > - 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; > > > > @@ -1544,6 +1539,27 @@ static int packed_delete_refs(struct ref_store *ref_store, const char *msg, > > if (!transaction) > > return -1; > > > > + ret = packed_refs_delete_refs(ref_store, transaction, > > + msg, refnames, flags); > > + > > + ref_transaction_free(transaction); > > + return ret; > > +} > > + > > +int packed_refs_delete_refs(struct ref_store *ref_store, > > + struct ref_transaction *transaction, > > + const char *msg, > > + struct string_list *refnames, > > + unsigned int flags) > > +{ > > + struct packed_ref_store *refs = > > + packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs"); > > + struct strbuf err = STRBUF_INIT; > > + struct string_list_item *item; > > + int ret; > > + > > + (void)(refs); /* We need the check above, but don't use the variable */ > > + > > for_each_string_list_item(item, refnames) { > > if (ref_transaction_delete(transaction, item->string, NULL, > > flags, msg, &err)) { > > I see you're just moving this code around, but FWIW we can just do this > (also in the pre-image): > > int packed_refs_delete_refs(...) > { > [declare variables] > > /* Assert ref store sanity */ > packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs") > > [...] > } > > Not sure it's good to change it around just for this mostly-move, just a > note... I think this change is trivial enough to make while at it. Patrick > > @@ -1554,7 +1570,6 @@ static int packed_delete_refs(struct ref_store *ref_store, const char *msg, > > } > > > > ret = ref_transaction_commit(transaction, &err); > > - > > Stray whitespace change.