Add a new flag REF_ISPACKONLY that we can use in ref_transaction_delete.
This flag indicates that the ref does not exist as a loose ref andf only as
a packed ref. If this is the case we then change the commit code so that
we skip taking out a lock file and we skip calling delete_ref_loose.
Check for this flag and die(BUG:...) if used with _update or _create.

At the start of the transaction, before we even start locking any refs,
we add all such REF_ISPACKONLY refs to delnames so that we have a list of
all pack only refs that we will be deleting during this transaction.

Signed-off-by: Ronnie Sahlberg <sahlb...@google.com>
---
 refs.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/refs.c b/refs.c
index a376dd6..6b8b7fe 100644
--- a/refs.c
+++ b/refs.c
@@ -33,6 +33,10 @@ static inline int bad_ref_char(int ch)
  *  pruned.
  */
 #define REF_ISPRUNING  0x0100
+/** Deletion of a ref that only exists as a packed ref in which case we do not
+ *  need to lock the loose ref during the transaction.
+ */
+#define REF_ISPACKONLY 0x0200
 
 /*
  * Try to read one refname component from the front of refname.  Return
@@ -3335,6 +3339,9 @@ int ref_transaction_update(struct ref_transaction 
*transaction,
        if (transaction->status != REF_TRANSACTION_OPEN)
                die("BUG: update on transaction that is not open");
 
+       if (flags & REF_ISPACKONLY)
+               die("BUG: REF_ISPACKONLY can not be used with updates");
+
        update = add_update(transaction, refname);
        hashcpy(update->new_sha1, new_sha1);
        update->flags = flags;
@@ -3359,6 +3366,9 @@ int ref_transaction_create(struct ref_transaction 
*transaction,
        if (transaction->status != REF_TRANSACTION_OPEN)
                die("BUG: create on transaction that is not open");
 
+       if (flags & REF_ISPACKONLY)
+               die("BUG: REF_ISPACKONLY can not be used with creates");
+
        update = add_update(transaction, refname);
 
        hashcpy(update->new_sha1, new_sha1);
@@ -3472,10 +3482,20 @@ int ref_transaction_commit(struct ref_transaction 
*transaction,
        if (ret)
                goto cleanup;
 
+       for (i = 0; i < n; i++) {
+               struct ref_update *update = updates[i];
+
+               if (update->flags & REF_ISPACKONLY)
+                       delnames[delnum++] = update->refname;
+       }
+
        /* Acquire all locks while verifying old values */
        for (i = 0; i < n; i++) {
                struct ref_update *update = updates[i];
 
+               if (update->flags & REF_ISPACKONLY)
+                       continue;
+
                update->lock = lock_ref_sha1_basic(update->refname,
                                                   (update->have_old ?
                                                    update->old_sha1 :
@@ -3513,6 +3533,9 @@ int ref_transaction_commit(struct ref_transaction 
*transaction,
        for (i = 0; i < n; i++) {
                struct ref_update *update = updates[i];
 
+               if (update->flags & REF_ISPACKONLY)
+                       continue;
+
                if (update->lock) {
                        ret |= delete_ref_loose(update->lock, update->type);
                        if (!(update->flags & REF_ISPRUNING))
-- 
2.0.0.rc3.471.g2055d11.dirty

--
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