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

4
refs.h
View File

@ -773,8 +773,10 @@ int ref_transaction_verify(struct ref_transaction *transaction,
/* Naming conflict (for example, the ref names A and A/B conflict). */
#define TRANSACTION_NAME_CONFLICT -1
/* When only creation was requested, but the ref already exists. */
#define TRANSACTION_CREATE_EXISTS -2
/* All other errors. */
#define TRANSACTION_GENERIC_ERROR -2
#define TRANSACTION_GENERIC_ERROR -3
/*
* Perform the preparatory stages of committing `transaction`. Acquire

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;
}
}
/*

View File

@ -1208,10 +1208,13 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store,
goto done;
}
} else if ((u->flags & REF_HAVE_OLD) && !oideq(&current_oid, &u->old_oid)) {
if (is_null_oid(&u->old_oid))
ret = TRANSACTION_NAME_CONFLICT;
if (is_null_oid(&u->old_oid)) {
strbuf_addf(err, _("cannot lock ref '%s': "
"reference already exists"),
ref_update_original_update_refname(u));
ret = TRANSACTION_CREATE_EXISTS;
}
else if (is_null_oid(&current_oid))
strbuf_addf(err, _("cannot lock ref '%s': "
"reference is missing but expected %s"),
@ -1223,7 +1226,6 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store,
ref_update_original_update_refname(u),
oid_to_hex(&current_oid),
oid_to_hex(&u->old_oid));
ret = -1;
goto done;
}