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 <sahlberg@xxxxxxxxxx> --- refs.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/refs.c b/refs.c index 87113af..6299b3d 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 @@ -3376,6 +3380,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; @@ -3402,6 +3409,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); @@ -3517,10 +3527,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 : @@ -3558,6 +3578,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, err); -- 2.0.0.rc3.477.gffe78a2 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html