initial_ref_transaction_commit(): check for ref D/F conflicts
In initial_ref_transaction_commit(), check for D/F conflicts (i.e., the type of conflict that exists between "refs/foo" and "refs/foo/bar") among the references being created and between the references being created and any hypothetical existing references. Ideally, there shouldn't *be* any existing references when this function is called. But, at least in the case of the "testgit" remote helper, "clone" can be called after the remote-tracking "HEAD" and "master" branches have already been created. So let's just do the full-blown check. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michael Haggerty committed
Jun 22, 2015 at 16:03 UTC
e426ff4222ba82a57ed459320509273dc8959ade
1 file changed
+34
refs.c
+34
@@ -4093,9 +4093,19 @@ cleanup:
4093
return ret;
4094
}
4095
4096
+static int ref_present(const char *refname,
4097
+ const struct object_id *oid, int flags, void *cb_data)
4098
+{
4099
+ struct string_list *affected_refnames = cb_data;
4100
+
4101
+ return string_list_has_string(affected_refnames, refname);
4102
+}
4103
+
4104
int initial_ref_transaction_commit(struct ref_transaction *transaction,
4105
struct strbuf *err)
4106
{
4107
+ struct ref_dir *loose_refs = get_loose_refs(&ref_cache);
4108
+ struct ref_dir *packed_refs = get_packed_refs(&ref_cache);
4109
int ret = 0, i;
4110
int n = transaction->nr;
4111
struct ref_update **updates = transaction->updates;
@@ -4115,12 +4125,36 @@ int initial_ref_transaction_commit(struct ref_transaction *transaction,
4125
goto cleanup;
4126
}
4127
4128
+ /*
4129
+ * It's really undefined to call this function in an active
4130
+ * repository or when there are existing references: we are
4131
+ * only locking and changing packed-refs, so (1) any
4132
+ * simultaneous processes might try to change a reference at
4133
+ * the same time we do, and (2) any existing loose versions of
4134
+ * the references that we are setting would have precedence
4135
+ * over our values. But some remote helpers create the remote
4136
+ * "HEAD" and "master" branches before calling this function,
4137
+ * so here we really only check that none of the references
4138
+ * that we are creating already exists.
4139
+ */
4140
+ if (for_each_rawref(ref_present, &affected_refnames))
4141
+ die("BUG: initial ref transaction called with existing refs");
4142
+
4143
for (i = 0; i < n; i++) {
4144
struct ref_update *update = updates[i];
4145
4146
if ((update->flags & REF_HAVE_OLD) &&
4147
!is_null_sha1(update->old_sha1))
4148
die("BUG: initial ref transaction with old_sha1 set");
4149
+ if (verify_refname_available(update->refname,
4150
+ &affected_refnames, NULL,
4151
+ loose_refs, err) ||
4152
+ verify_refname_available(update->refname,
4153
+ &affected_refnames, NULL,
4154
+ packed_refs, err)) {
4155
+ ret = TRANSACTION_NAME_CONFLICT;
4156
+ goto cleanup;
4157
+ }
4158
}
4159
4160
if (lock_packed_refs(0)) {