summaryrefslogtreecommitdiff
path: root/refs
diff options
context:
space:
mode:
authorLibravatar Michael Haggerty <mhagger@alum.mit.edu>2017-09-08 15:51:46 +0200
committerLibravatar Junio C Hamano <gitster@pobox.com>2017-09-09 03:18:04 +0900
commit2fb330ca7238088eea5c1926380feb187f4867bc (patch)
tree93dedf7ea3435e72a5fab58a73456eeaa5ab301a /refs
parentpacked_ref_store: implement reference transactions (diff)
downloadtgif-2fb330ca7238088eea5c1926380feb187f4867bc.tar.xz
packed_delete_refs(): implement method
Implement `packed_delete_refs()` using a reference transaction. This means that `files_delete_refs()` can use `refs_delete_refs()` instead of `repack_without_refs()` to delete any packed references, decreasing the coupling between the classes. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs')
-rw-r--r--refs/files-backend.c2
-rw-r--r--refs/packed-backend.c45
2 files changed, 45 insertions, 2 deletions
diff --git a/refs/files-backend.c b/refs/files-backend.c
index fccbc24ac4..2c78f63494 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1157,7 +1157,7 @@ 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 (repack_without_refs(refs->packed_ref_store, refnames, &err)) {
+ if (refs_delete_refs(refs->packed_ref_store, msg, refnames, flags)) {
packed_refs_unlock(refs->packed_ref_store);
goto error;
}
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index 9ab65c5a0a..9d5f76b1dc 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -1086,7 +1086,50 @@ 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)
{
- die("BUG: not implemented yet");
+ 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;
+
+ /*
+ * 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, unsigned int flags)