summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonnie Sahlberg <sahlberg@google.com>2014-05-15 10:29:49 -0700
committerJunio C Hamano <gitster@pobox.com>2014-05-15 14:12:17 -0700
commit456f3228a53509b79aaaf66bb97bd78b6decf91b (patch)
treee59dbb740e0d6f50936b6ef8eb3f658bd90803fd
parenta87e58d8d3e8d6d12ad7ab96c3c5c53c7b82ce39 (diff)
downloadgit-456f3228a53509b79aaaf66bb97bd78b6decf91b.tar.gz
refs.c: make prune_ref use a transaction to delete the ref
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. This flag is private to refs.c and not exposed to external callers. Signed-off-by: Ronnie Sahlberg <sahlberg@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--refs.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/refs.c b/refs.c
index f1ef940d49..88ab01209b 100644
--- a/refs.c
+++ b/refs.c
@@ -29,6 +29,11 @@ static inline int bad_ref_char(int ch)
return 0;
}
+/** Used as a flag to ref_transaction_delete when a loose ref is beeing
+ * pruned.
+ */
+#define REF_ISPRUNING 0x0100
+
/*
* Try to read one refname component from the front of refname. Return
* the length of the component found, or -1 if the component is not
@@ -2326,17 +2331,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)
@@ -3512,9 +3524,10 @@ 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,
err);
+ if (!(update->flags & REF_ISPRUNING))
+ delnames[delnum++] = update->lock->ref_name;
}
}