summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonnie Sahlberg <sahlberg@google.com>2014-05-15 10:29:56 -0700
committerJunio C Hamano <gitster@pobox.com>2014-05-15 14:12:36 -0700
commitd2a5f10970852e85531b17cc5afcba2df4477e29 (patch)
treea9d6cc9f9c4b882b8e403d49d89466fbc5e36549
parent693acd671c03684398880ce6134ce48012444f45 (diff)
downloadgit-d2a5f10970852e85531b17cc5afcba2df4477e29.tar.gz
refs.c: add a new flag for transaction delete for refs we know are packed only
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@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--refs.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/refs.c b/refs.c
index 69ad51d62e..f458ff9f9d 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
@@ -3346,6 +3350,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;
@@ -3370,6 +3377,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);
@@ -3483,10 +3493,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 :
@@ -3524,6 +3544,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);