aboutsummaryrefslogtreecommitdiffstats
path: root/refs.c
diff options
context:
space:
mode:
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/refs.c b/refs.c
index 79d5a8b8d4..22000798c7 100644
--- a/refs.c
+++ b/refs.c
@@ -1175,6 +1175,7 @@ struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs,
CALLOC_ARRAY(tr, 1);
tr->ref_store = refs;
tr->flags = flags;
+ string_list_init_dup(&tr->refnames);
return tr;
}
@@ -1205,6 +1206,7 @@ void ref_transaction_free(struct ref_transaction *transaction)
free((char *)transaction->updates[i]->old_target);
free(transaction->updates[i]);
}
+ string_list_clear(&transaction->refnames, 0);
free(transaction->updates);
free(transaction);
}
@@ -1218,6 +1220,7 @@ struct ref_update *ref_transaction_add_update(
const char *committer_info,
const char *msg)
{
+ struct string_list_item *item;
struct ref_update *update;
if (transaction->state != REF_TRANSACTION_OPEN)
@@ -1245,6 +1248,16 @@ struct ref_update *ref_transaction_add_update(
update->msg = normalize_reflog_message(msg);
}
+ /*
+ * This list is generally used by the backends to avoid duplicates.
+ * But we do support multiple log updates for a given refname within
+ * a single transaction.
+ */
+ if (!(update->flags & REF_LOG_ONLY)) {
+ item = string_list_append(&transaction->refnames, refname);
+ item->util = update;
+ }
+
return update;
}
@@ -2405,6 +2418,10 @@ int ref_transaction_prepare(struct ref_transaction *transaction,
return -1;
}
+ string_list_sort(&transaction->refnames);
+ if (ref_update_reject_duplicates(&transaction->refnames, err))
+ return TRANSACTION_GENERIC_ERROR;
+
ret = refs->be->transaction_prepare(refs, transaction, err);
if (ret)
return ret;