3376
update->new_sha1, update->old_sha1,
3377
update->msg);
3378
3379
- /* Change the symbolic ref update to log only: */
3379
+ new_update->parent_update = update;
3380
+
3381
+ /*
3382
+ * Change the symbolic ref update to log only. Also, it
3383
+ * doesn't need to check its old SHA-1 value, as that will be
3384
+ * done when new_update is processed.
3385
+ */
3386
update->flags |= REF_LOG_ONLY | REF_NODEREF;
3387
+ update->flags &= ~REF_HAVE_OLD;
3388
3389
item->util = new_update;
3390
3391
return 0;
3392
}
3393
3394
+/*
3395
+ * Return the refname under which update was originally requested.
3396
+ */
3397
+static const char *original_update_refname(struct ref_update *update)
3398
+{
3399
+ while (update->parent_update)
3400
+ update = update->parent_update;
3401
+
3402
+ return update->refname;
3403
+}
3404
+
3405
/*
3406
* Prepare for carrying out update:
3407
* - Lock the reference referred to by update.
3455
lock = update->lock;
3456
3457
if (update->type & REF_ISSYMREF) {
3440
- if (read_ref_full(update->refname,
3441
- mustexist ? RESOLVE_REF_READING : 0,
3442
- lock->old_oid.hash, NULL)) {
3443
- if (update->flags & REF_HAVE_OLD) {
3444
- strbuf_addf(err, "cannot lock ref '%s': can't resolve old value",
3445
- update->refname);
3458
+ if (update->flags & REF_NODEREF) {
3459
+ /*
3460
+ * We won't be reading the referent as part of
3461
+ * the transaction, so we have to read it here
3462
+ * to record and possibly check old_sha1:
3463
+ */
3464
+ if (read_ref_full(update->refname,
3465
+ mustexist ? RESOLVE_REF_READING : 0,
3466
+ lock->old_oid.hash, NULL)) {
3467
+ if (update->flags & REF_HAVE_OLD) {
3468
+ strbuf_addf(err, "cannot lock ref '%s': "
3469
+ "can't resolve old value",
3470
+ update->refname);
3471
+ return TRANSACTION_GENERIC_ERROR;
3472
+ } else {
3473
+ hashclr(lock->old_oid.hash);
3474
+ }
3475
+ }
3476
+ if ((update->flags & REF_HAVE_OLD) &&
3477
+ hashcmp(lock->old_oid.hash, update->old_sha1)) {
3478
+ strbuf_addf(err, "cannot lock ref '%s': "
3479
+ "is at %s but expected %s",
3480
+ update->refname,
3481
+ sha1_to_hex(lock->old_oid.hash),
3482
+ sha1_to_hex(update->old_sha1));
3483
return TRANSACTION_GENERIC_ERROR;
3447
- } else {
3448
- hashclr(lock->old_oid.hash);
3484
}
3450
- }
3451
- if ((update->flags & REF_HAVE_OLD) &&
3452
- hashcmp(lock->old_oid.hash, update->old_sha1)) {
3453
- strbuf_addf(err, "cannot lock ref '%s': is at %s but expected %s",
3454
- update->refname,
3455
- sha1_to_hex(lock->old_oid.hash),
3456
- sha1_to_hex(update->old_sha1));
3457
- return TRANSACTION_GENERIC_ERROR;
3458
- }
3485
3460
- if (!(update->flags & REF_NODEREF)) {
3486
+ } else {
3487
+ /*
3488
+ * Create a new update for the reference this
3489
+ * symref is pointing at. Also, we will record
3490
+ * and verify old_sha1 for this update as part
3491
+ * of processing the split-off update, so we
3492
+ * don't have to do it here.
3493
+ */
3494
ret = split_symref_update(update, referent.buf, transaction,
3495
affected_refnames, err);
3496
if (ret)
3497
return ret;
3498
}
3466
- } else if ((update->flags & REF_HAVE_OLD) &&
3467
- hashcmp(lock->old_oid.hash, update->old_sha1)) {
3468
- if (is_null_sha1(update->old_sha1))
3469
- strbuf_addf(err, "cannot lock ref '%s': reference already exists",
3470
- update->refname);
3471
- else
3472
- strbuf_addf(err, "cannot lock ref '%s': is at %s but expected %s",
3473
- update->refname,
3474
- sha1_to_hex(lock->old_oid.hash),
3475
- sha1_to_hex(update->old_sha1));
3499
+ } else {
3500
+ struct ref_update *parent_update;
3501
+
3502
+ /*
3503
+ * If this update is happening indirectly because of a
3504
+ * symref update, record the old SHA-1 in the parent
3505
+ * update:
3506
+ */
3507
+ for (parent_update = update->parent_update;
3508
+ parent_update;
3509
+ parent_update = parent_update->parent_update) {
3510
+ oidcpy(&parent_update->lock->old_oid, &lock->old_oid);
3511
+ }
3512
3477
- return TRANSACTION_GENERIC_ERROR;
3513
+ if ((update->flags & REF_HAVE_OLD) &&
3514
+ hashcmp(lock->old_oid.hash, update->old_sha1)) {
3515
+ if (is_null_sha1(update->old_sha1))
3516
+ strbuf_addf(err, "cannot lock ref '%s': reference already exists",
3517
+ original_update_refname(update));
3518
+ else
3519
+ strbuf_addf(err, "cannot lock ref '%s': is at %s but expected %s",
3520
+ original_update_refname(update),
3521
+ sha1_to_hex(lock->old_oid.hash),
3522
+ sha1_to_hex(update->old_sha1));
3523
+
3524
+ return TRANSACTION_GENERIC_ERROR;
3525
+ }
3526
}
3527
3528
if ((update->flags & REF_HAVE_NEW) &&