3237
return update_ref_write(action, refname, sha1, lock, onerr);
3238
}
3239
3240
+static int ref_update_compare(const void *r1, const void *r2)
3241
+{
3242
+ const struct ref_update * const *u1 = r1;
3243
+ const struct ref_update * const *u2 = r2;
3244
+ return strcmp((*u1)->ref_name, (*u2)->ref_name);
3245
+}
3246
+
3247
+static int ref_update_reject_duplicates(struct ref_update **updates, int n,
3248
+ enum action_on_err onerr)
3249
+{
3250
+ int i;
3251
+ for (i = 1; i < n; i++)
3252
+ if (!strcmp(updates[i - 1]->ref_name, updates[i]->ref_name)) {
3253
+ const char *str =
3254
+ "Multiple updates for ref '%s' not allowed.";
3255
+ switch (onerr) {
3256
+ case MSG_ON_ERR:
3257
+ error(str, updates[i]->ref_name); break;
3258
+ case DIE_ON_ERR:
3259
+ die(str, updates[i]->ref_name); break;
3260
+ case QUIET_ON_ERR:
3261
+ break;
3262
+ }
3263
+ return 1;
3264
+ }
3265
+ return 0;
3266
+}
3267
+
3268
+int update_refs(const char *action, const struct ref_update **updates_orig,
3269
+ int n, enum action_on_err onerr)
3270
+{
3271
+ int ret = 0, delnum = 0, i;
3272
+ struct ref_update **updates;
3273
+ int *types;
3274
+ struct ref_lock **locks;
3275
+ const char **delnames;
3276
+
3277
+ if (!updates_orig || !n)
3278
+ return 0;
3279
+
3280
+ /* Allocate work space */
3281
+ updates = xmalloc(sizeof(*updates) * n);
3282
+ types = xmalloc(sizeof(*types) * n);
3283
+ locks = xcalloc(n, sizeof(*locks));
3284
+ delnames = xmalloc(sizeof(*delnames) * n);
3285
+
3286
+ /* Copy, sort, and reject duplicate refs */
3287
+ memcpy(updates, updates_orig, sizeof(*updates) * n);
3288
+ qsort(updates, n, sizeof(*updates), ref_update_compare);
3289
+ ret = ref_update_reject_duplicates(updates, n, onerr);
3290
+ if (ret)
3291
+ goto cleanup;
3292
+
3293
+ /* Acquire all locks while verifying old values */
3294
+ for (i = 0; i < n; i++) {
3295
+ locks[i] = update_ref_lock(updates[i]->ref_name,
3296
+ (updates[i]->have_old ?
3297
+ updates[i]->old_sha1 : NULL),
3298
+ updates[i]->flags,
3299
+ &types[i], onerr);
3300
+ if (!locks[i]) {
3301
+ ret = 1;
3302
+ goto cleanup;
3303
+ }
3304
+ }
3305
+
3306
+ /* Perform updates first so live commits remain referenced */
3307
+ for (i = 0; i < n; i++)
3308
+ if (!is_null_sha1(updates[i]->new_sha1)) {
3309
+ ret = update_ref_write(action,
3310
+ updates[i]->ref_name,
3311
+ updates[i]->new_sha1,
3312
+ locks[i], onerr);
3313
+ locks[i] = NULL; /* freed by update_ref_write */
3314
+ if (ret)
3315
+ goto cleanup;
3316
+ }
3317
+
3318
+ /* Perform deletes now that updates are safely completed */
3319
+ for (i = 0; i < n; i++)
3320
+ if (locks[i]) {
3321
+ delnames[delnum++] = locks[i]->ref_name;
3322
+ ret |= delete_ref_loose(locks[i], types[i]);
3323
+ }
3324
+ ret |= repack_without_refs(delnames, delnum);
3325
+ for (i = 0; i < delnum; i++)
3326
+ unlink_or_warn(git_path("logs/%s", delnames[i]));
3327
+ clear_loose_ref_cache(&ref_cache);
3328
+
3329
+cleanup:
3330
+ for (i = 0; i < n; i++)
3331
+ if (locks[i])
3332
+ unlock_ref(locks[i]);
3333
+ free(updates);
3334
+ free(types);
3335
+ free(locks);
3336
+ free(delnames);
3337
+ return ret;
3338
+}
3339
+
3340
struct ref *find_ref_by_name(const struct ref *list, const char *name)
3341
{
3342
for ( ; list; list = list->next)