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). */ /* Naming conflict (for example, the ref names A and A/B conflict). */
#define TRANSACTION_NAME_CONFLICT -1 #define TRANSACTION_NAME_CONFLICT -1
/* When only creation was requested, but the ref already exists. */
#define TRANSACTION_CREATE_EXISTS -2
/* All other errors. */ /* All other errors. */
#define TRANSACTION_GENERIC_ERROR -2 #define TRANSACTION_GENERIC_ERROR -3
/* /*
* Perform the preparatory stages of committing `transaction`. Acquire * 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, static int check_old_oid(struct ref_update *update, struct object_id *oid,
struct strbuf *err) struct strbuf *err)
{ {
int ret = TRANSACTION_GENERIC_ERROR;
if (!(update->flags & REF_HAVE_OLD) || if (!(update->flags & REF_HAVE_OLD) ||
oideq(oid, &update->old_oid)) oideq(oid, &update->old_oid))
return 0; return 0;
if (is_null_oid(&update->old_oid)) if (is_null_oid(&update->old_oid)) {
strbuf_addf(err, "cannot lock ref '%s': " strbuf_addf(err, "cannot lock ref '%s': "
"reference already exists", "reference already exists",
ref_update_original_update_refname(update)); ref_update_original_update_refname(update));
ret = TRANSACTION_CREATE_EXISTS;
}
else if (is_null_oid(oid)) else if (is_null_oid(oid))
strbuf_addf(err, "cannot lock ref '%s': " strbuf_addf(err, "cannot lock ref '%s': "
"reference is missing but expected %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(oid),
oid_to_hex(&update->old_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; ret = TRANSACTION_GENERIC_ERROR;
goto out; goto out;
} }
} else if (check_old_oid(update, &lock->old_oid, err)) { } else {
ret = TRANSACTION_GENERIC_ERROR; ret = check_old_oid(update, &lock->old_oid, err);
goto out; if (ret) {
goto out;
}
} }
} else { } else {
/* /*
@ -2634,9 +2640,11 @@ static int lock_ref_for_update(struct files_ref_store *refs,
update->old_target); update->old_target);
ret = TRANSACTION_GENERIC_ERROR; ret = TRANSACTION_GENERIC_ERROR;
goto out; goto out;
} else if (check_old_oid(update, &lock->old_oid, err)) { } else {
ret = TRANSACTION_GENERIC_ERROR; ret = check_old_oid(update, &lock->old_oid, err);
goto out; if (ret) {
goto out;
}
} }
/* /*

View File

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