refs: specify error for regular refs with `old_target`

When a reference update tries to update a symref, but the ref in question is actually a regular ref, we raise an error. However the error raised in this situation is: verifying symref target: '<ref>': reference is missing but expected <old-target> which is very generic and doesn't indicate the mismatch of types. Let's make this error more specific: cannot lock ref '<ref>': expected symref with target '<old-target>': but is a regular ref so that users have a clearer understanding. Signed-off-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Karthik Nayak committed Jun 7, 2024 at 15:32 UTC aa6e99f1226fe46f1649f48d020011e19556e8e1
2 files changed +18 -6
refs/files-backend.c
+8 -6
@@ -2490,14 +2490,16 @@ static int lock_ref_for_update(struct files_ref_store *refs,
2490
2491 /*
2492 * Even if the ref is a regular ref, if `old_target` is set, we
2493 - * check the referent value. Ideally `old_target` should only
2494 - * be set for symrefs, but we're strict about its usage.
2493 + * fail with an error.
2494 */
2495 if (update->old_target) {
2497 - if (ref_update_check_old_target(referent.buf, update, err)) {
2498 - ret = TRANSACTION_GENERIC_ERROR;
2499 - goto out;
2500 - }
2496 + strbuf_addf(err, _("cannot lock ref '%s': "
2497 + "expected symref with target '%s': "
2498 + "but is a regular ref"),
2499 + ref_update_original_update_refname(update),
2500 + update->old_target);
2501 + ret = TRANSACTION_GENERIC_ERROR;
2502 + goto out;
2503 } else if (check_old_oid(update, &lock->old_oid, err)) {
2504 ret = TRANSACTION_GENERIC_ERROR;
2505 goto out;
refs/reftable-backend.c
+10
@@ -931,6 +931,16 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store,
931 * backend returns, which keeps our tests happy.
932 */
933 if (u->old_target) {
934 + if (!(u->type & REF_ISSYMREF)) {
935 + strbuf_addf(err, _("cannot lock ref '%s': "
936 + "expected symref with target '%s': "
937 + "but is a regular ref"),
938 + ref_update_original_update_refname(u),
939 + u->old_target);
940 + ret = -1;
941 + goto done;
942 + }
943 +
944 if (ref_update_check_old_target(referent.buf, u, err)) {
945 ret = -1;
946 goto done;