[PATCH v6 39/42] refs.c: add a new flag for transaction delete for refs we know are packed only
From: Ronnie Sahlberg <hidden>
Date: 2016-06-15 23:00:57
Subsystem:
the rest · Maintainer:
Linus Torvalds
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 <redacted> --- refs.c | 19 +++++++++++++++++++ refs.h | 2 ++ 2 files changed, 21 insertions(+)
diff --git a/refs.c b/refs.c
index 51cd41e..b525076 100644
--- a/refs.c
+++ b/refs.c@@ -3321,6 +3321,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;
@@ -3345,6 +3348,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);
@@ -3458,10 +3464,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 :
@@ -3499,6 +3515,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))
diff --git a/refs.h b/refs.h
index 7a89415..71e39b9 100644
--- a/refs.h
+++ b/refs.h@@ -136,6 +136,8 @@ extern int peel_ref(const char *refname, unsigned char *sha1); #define REF_NODEREF 0x01 /** Deleting a loose ref during prune */ #define REF_ISPRUNING 0x02 +/** Deletion of a ref that only exists as a packed ref */ +#define REF_ISPACKONLY 0x04 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