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>
Bence Ferdinandy committed
Nov 22, 2024 at 13:28 UTC
ed2f6f8804cc142a02c701e808d110223b0256f8
3 files changed
+23
-11
refs.h
+3
-1
@@ -773,8 +773,10 @@ int ref_transaction_verify(struct ref_transaction *transaction,
773
774
/* Naming conflict (for example, the ref names A and A/B conflict). */
775
#define TRANSACTION_NAME_CONFLICT -1
776
+/* When only creation was requested, but the ref already exists. */
777
+#define TRANSACTION_CREATE_EXISTS -2
778
/* All other errors. */
777
-#define TRANSACTION_GENERIC_ERROR -2
779
+#define TRANSACTION_GENERIC_ERROR -3
780
781
/*
782
* Perform the preparatory stages of committing `transaction`. Acquire
refs/files-backend.c
+16
-8
@@ -2501,14 +2501,18 @@ static int split_symref_update(struct ref_update *update,
2501
static int check_old_oid(struct ref_update *update, struct object_id *oid,
2502
struct strbuf *err)
2503
{
2504
+ int ret = TRANSACTION_GENERIC_ERROR;
2505
+
2506
if (!(update->flags & REF_HAVE_OLD) ||
2507
oideq(oid, &update->old_oid))
2508
return 0;
2509
2508
- if (is_null_oid(&update->old_oid))
2510
+ if (is_null_oid(&update->old_oid)) {
2511
strbuf_addf(err, "cannot lock ref '%s': "
2512
"reference already exists",
2513
ref_update_original_update_refname(update));
2514
+ ret = TRANSACTION_CREATE_EXISTS;
2515
+ }
2516
else if (is_null_oid(oid))
2517
strbuf_addf(err, "cannot lock ref '%s': "
2518
"reference is missing but expected %s",
@@ -2521,7 +2525,7 @@ static int check_old_oid(struct ref_update *update, struct object_id *oid,
2525
oid_to_hex(oid),
2526
oid_to_hex(&update->old_oid));
2527
2524
- return -1;
2528
+ return ret;
2529
}
2530
2531
/*
@@ -2601,9 +2605,11 @@ static int lock_ref_for_update(struct files_ref_store *refs,
2605
ret = TRANSACTION_GENERIC_ERROR;
2606
goto out;
2607
}
2604
- } else if (check_old_oid(update, &lock->old_oid, err)) {
2605
- ret = TRANSACTION_GENERIC_ERROR;
2606
- goto out;
2608
+ } else {
2609
+ ret = check_old_oid(update, &lock->old_oid, err);
2610
+ if (ret) {
2611
+ goto out;
2612
+ }
2613
}
2614
} else {
2615
/*
@@ -2634,9 +2640,11 @@ static int lock_ref_for_update(struct files_ref_store *refs,
2640
update->old_target);
2641
ret = TRANSACTION_GENERIC_ERROR;
2642
goto out;
2637
- } else if (check_old_oid(update, &lock->old_oid, err)) {
2638
- ret = TRANSACTION_GENERIC_ERROR;
2639
- goto out;
2643
+ } else {
2644
+ ret = check_old_oid(update, &lock->old_oid, err);
2645
+ if (ret) {
2646
+ goto out;
2647
+ }
2648
}
2649
2650
/*
refs/reftable-backend.c
+4
-2
@@ -1208,10 +1208,13 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store,
1208
goto done;
1209
}
1210
} else if ((u->flags & REF_HAVE_OLD) && !oideq(¤t_oid, &u->old_oid)) {
1211
- if (is_null_oid(&u->old_oid))
1211
+ ret = TRANSACTION_NAME_CONFLICT;
1212
+ if (is_null_oid(&u->old_oid)) {
1213
strbuf_addf(err, _("cannot lock ref '%s': "
1214
"reference already exists"),
1215
ref_update_original_update_refname(u));
1216
+ ret = TRANSACTION_CREATE_EXISTS;
1217
+ }
1218
else if (is_null_oid(¤t_oid))
1219
strbuf_addf(err, _("cannot lock ref '%s': "
1220
"reference is missing but expected %s"),
@@ -1223,7 +1226,6 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store,
1226
ref_update_original_update_refname(u),
1227
oid_to_hex(¤t_oid),
1228
oid_to_hex(&u->old_oid));
1226
- ret = -1;
1229
goto done;
1230
}
1231