initial_ref_transaction_commit(): check for duplicate refs
authorMichael Haggerty <mhagger@alum.mit.edu>
Mon, 22 Jun 2015 14:03:03 +0000 (16:03 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 22 Jun 2015 20:17:11 +0000 (13:17 -0700)
Error out if the ref_transaction includes more than one update for any
refname.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
refs.c
diff --git a/refs.c b/refs.c
index 6380a0970acae4ae1cc5ad1139c0abcbdfd0fbe4..388ac3ed357212fd40139ebc1533c80b78a3fb60 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -4099,12 +4099,22 @@ int initial_ref_transaction_commit(struct ref_transaction *transaction,
        int ret = 0, i;
        int n = transaction->nr;
        struct ref_update **updates = transaction->updates;
+       struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
 
        assert(err);
 
        if (transaction->state != REF_TRANSACTION_OPEN)
                die("BUG: commit called for transaction that is not open");
 
+       /* Fail if a refname appears more than once in the transaction: */
+       for (i = 0; i < n; i++)
+               string_list_append(&affected_refnames, updates[i]->refname);
+       string_list_sort(&affected_refnames);
+       if (ref_update_reject_duplicates(&affected_refnames, err)) {
+               ret = TRANSACTION_GENERIC_ERROR;
+               goto cleanup;
+       }
+
        for (i = 0; i < n; i++) {
                struct ref_update *update = updates[i];
 
@@ -4137,6 +4147,7 @@ int initial_ref_transaction_commit(struct ref_transaction *transaction,
 
 cleanup:
        transaction->state = REF_TRANSACTION_CLOSED;
+       string_list_clear(&affected_refnames, 0);
        return ret;
 }