refs: add TRANSACTION_CREATE_EXISTS error

Currently there is only one special error for transaction, for when
there is a naming conflict, all other errors are dumped under a generic
error. Add a new special error case for when the caller requests the
reference to be updated only when it does not yet exist and the
reference actually does exist.

Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Bence Ferdinandy
2024-11-22 13:28:48 +01:00
committed by Junio C Hamano
parent dfe86fa06b
commit ed2f6f8804
3 changed files with 23 additions and 11 deletions

View File

@ -2501,14 +2501,18 @@ static int split_symref_update(struct ref_update *update,
static int check_old_oid(struct ref_update *update, struct object_id *oid,
struct strbuf *err)
{
int ret = TRANSACTION_GENERIC_ERROR;
if (!(update->flags & REF_HAVE_OLD) ||
oideq(oid, &update->old_oid))
return 0;
if (is_null_oid(&update->old_oid))
if (is_null_oid(&update->old_oid)) {
strbuf_addf(err, "cannot lock ref '%s': "
"reference already exists",
ref_update_original_update_refname(update));
ret = TRANSACTION_CREATE_EXISTS;
}
else if (is_null_oid(oid))
strbuf_addf(err, "cannot lock ref '%s': "
"reference is missing but expected %s",
@ -2521,7 +2525,7 @@ static int check_old_oid(struct ref_update *update, struct object_id *oid,
oid_to_hex(oid),
oid_to_hex(&update->old_oid));
return -1;
return ret;
}
/*
@ -2601,9 +2605,11 @@ static int lock_ref_for_update(struct files_ref_store *refs,
ret = TRANSACTION_GENERIC_ERROR;
goto out;
}
} else if (check_old_oid(update, &lock->old_oid, err)) {
ret = TRANSACTION_GENERIC_ERROR;
goto out;
} else {
ret = check_old_oid(update, &lock->old_oid, err);
if (ret) {
goto out;
}
}
} else {
/*
@ -2634,9 +2640,11 @@ static int lock_ref_for_update(struct files_ref_store *refs,
update->old_target);
ret = TRANSACTION_GENERIC_ERROR;
goto out;
} else if (check_old_oid(update, &lock->old_oid, err)) {
ret = TRANSACTION_GENERIC_ERROR;
goto out;
} else {
ret = check_old_oid(update, &lock->old_oid, err);
if (ret) {
goto out;
}
}
/*