Change prune_ref to delete the ref using a ref transaction. To do this we also
need to add a new flag REF_ISPRUNING that will tell the transaction that we
do not want to delete this ref from the packed refs.

Signed-off-by: Ronnie Sahlberg <sahlb...@google.com>
---
 refs.c | 22 +++++++++++++++-------
 refs.h |  2 ++
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/refs.c b/refs.c
index a55cc38..2b82dce 100644
--- a/refs.c
+++ b/refs.c
@@ -2330,17 +2330,24 @@ static void try_remove_empty_parents(char *name)
 /* make sure nobody touched the ref, and unlink */
 static void prune_ref(struct ref_to_prune *r)
 {
-       struct ref_lock *lock;
+       struct ref_transaction *transaction;
+       struct strbuf err = STRBUF_INIT;
 
        if (check_refname_format(r->name + 5, 0))
                return;
 
-       lock = lock_ref_sha1_basic(r->name, r->sha1, 0, NULL);
-       if (lock) {
-               unlink_or_warn(git_path("%s", r->name));
-               unlock_ref(lock);
-               try_remove_empty_parents(r->name);
+       transaction = ref_transaction_begin();
+       if (!transaction ||
+           ref_transaction_delete(transaction, r->name, r->sha1,
+                                  REF_ISPRUNING, 1) ||
+           ref_transaction_commit(transaction, NULL, &err)) {
+               ref_transaction_rollback(transaction);
+               warning("prune_ref: %s", err.buf);
+               strbuf_release(&err);
+               return;
        }
+       ref_transaction_free(transaction);
+       try_remove_empty_parents(r->name);
 }
 
 static void prune_refs(struct ref_to_prune *r)
@@ -3492,8 +3499,9 @@ int ref_transaction_commit(struct ref_transaction 
*transaction,
                struct ref_update *update = updates[i];
 
                if (update->lock) {
-                       delnames[delnum++] = update->lock->ref_name;
                        ret |= delete_ref_loose(update->lock, update->type);
+                       if (!(update->flags & REF_ISPRUNING))
+                               delnames[delnum++] = update->lock->ref_name;
                }
        }
 
diff --git a/refs.h b/refs.h
index b14fe86..340e11a 100644
--- a/refs.h
+++ b/refs.h
@@ -134,6 +134,8 @@ extern int peel_ref(const char *refname, unsigned char 
*sha1);
 
 /** Locks any ref (for 'HEAD' type refs). */
 #define REF_NODEREF    0x01
+/** Deleting a loose ref during prune */
+#define REF_ISPRUNING  0x02
 extern struct ref_lock *lock_any_ref_for_update(const char *refname,
                                                const unsigned char *old_sha1,
                                                int flags, int *type_p);
-- 
2.0.0.rc1.351.g4d2c8e4

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to