diff --git a/refs.c b/refs.c
index 2d9789f..4f7ae92 100644
--- a/refs.c
+++ b/refs.c
@@ -3336,6 +3336,12 @@ struct ref_update {
const char refname[FLEX_ARRAY];
};
+enum ref_transaction_status {
+ REF_TRANSACTION_OPEN = 0,
+ REF_TRANSACTION_CLOSED = 1,
+ REF_TRANSACTION_ERROR = 2,
+};
+
/*
* Data structure for holding a reference transaction, which can
* consist of checks and updates to multiple references, carried out@@ -3345,6 +3351,7 @@ struct ref_transaction {
struct ref_update **updates;
size_t alloc;
size_t nr;
+ enum ref_transaction_status status;
};
struct ref_transaction *ref_transaction_begin(void)@@ -3390,6 +3397,9 @@ int ref_transaction_update(struct ref_transaction *transaction,
if (have_old && !old_sha1)
die("BUG: have_old is true but old_sha1 is NULL");
+ if (transaction->status != REF_TRANSACTION_OPEN)
+ die("BUG: update on transaction that is not open");
+
update = add_update(transaction, refname);
hashcpy(update->new_sha1, new_sha1);
update->flags = flags;@@ -3410,6 +3420,9 @@ int ref_transaction_create(struct ref_transaction *transaction,
if (!new_sha1 || is_null_sha1(new_sha1))
die("BUG: create ref with null new_sha1");
+ if (transaction->status != REF_TRANSACTION_OPEN)
+ die("BUG: create on transaction that is not open");
+
update = add_update(transaction, refname);
hashcpy(update->new_sha1, new_sha1);@@ -3430,6 +3443,9 @@ int ref_transaction_delete(struct ref_transaction *transaction,
if (have_old && !old_sha1)
die("BUG: have_old is true but old_sha1 is NULL");
+ if (transaction->status != REF_TRANSACTION_OPEN)
+ die("BUG: delete on transaction that is not open");
+
update = add_update(transaction, refname);
update->flags = flags;
update->have_old = have_old;@@ -3500,8 +3516,13 @@ int ref_transaction_commit(struct ref_transaction *transaction,
int n = transaction->nr;
struct ref_update **updates = transaction->updates;
- if (!n)
+ if (transaction->status != REF_TRANSACTION_OPEN)
+ die("BUG: commit on transaction that is not open");
+
+ if (!n) {
+ transaction->status = REF_TRANSACTION_CLOSED;
return 0;
+ }
/* Allocate work space */
delnames = xmalloc(sizeof(*delnames) * n);@@ -3564,6 +3585,9 @@ int ref_transaction_commit(struct ref_transaction *transaction,
clear_loose_ref_cache(&ref_cache);
cleanup:
+ transaction->status = ret ? REF_TRANSACTION_ERROR
+ : REF_TRANSACTION_CLOSED;
+
for (i = 0; i < n; i++)
if (updates[i]->lock)
unlock_ref(updates[i]->lock);
--
2.0.0.rc3.510.g20c254b