Skip to content

Commit 76e760b

Browse files
KarthikNayakgitster
authored andcommitted
refs: introduce enum-based transaction error types
Replace preprocessor-defined transaction errors with a strongly-typed enum `ref_transaction_error`. This change: - Improves type safety and function signature clarity. - Makes error handling more explicit and discoverable. - Maintains existing error cases, while adding new error cases for common scenarios. This refactoring paves the way for more comprehensive error handling which we will utilize in the upcoming commits to add batch reference update support. Signed-off-by: Karthik Nayak <[email protected]> Acked-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ca89c18 commit 76e760b

File tree

7 files changed

+207
-186
lines changed

7 files changed

+207
-186
lines changed

builtin/fetch.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ static int s_update_ref(const char *action,
687687
switch (ref_transaction_commit(our_transaction, &err)) {
688688
case 0:
689689
break;
690-
case TRANSACTION_NAME_CONFLICT:
690+
case REF_TRANSACTION_ERROR_NAME_CONFLICT:
691691
ret = STORE_REF_ERROR_DF_CONFLICT;
692692
goto out;
693693
default:

refs.c

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2271,7 +2271,7 @@ int refs_update_symref_extended(struct ref_store *refs, const char *ref,
22712271
REF_NO_DEREF, logmsg, &err))
22722272
goto error_return;
22732273
prepret = ref_transaction_prepare(transaction, &err);
2274-
if (prepret && prepret != TRANSACTION_CREATE_EXISTS)
2274+
if (prepret && prepret != REF_TRANSACTION_ERROR_CREATE_EXISTS)
22752275
goto error_return;
22762276
} else {
22772277
if (ref_transaction_update(transaction, ref, NULL, NULL,
@@ -2289,7 +2289,7 @@ int refs_update_symref_extended(struct ref_store *refs, const char *ref,
22892289
}
22902290
}
22912291

2292-
if (prepret == TRANSACTION_CREATE_EXISTS)
2292+
if (prepret == REF_TRANSACTION_ERROR_CREATE_EXISTS)
22932293
goto cleanup;
22942294

22952295
if (ref_transaction_commit(transaction, &err))
@@ -2425,7 +2425,7 @@ int ref_transaction_prepare(struct ref_transaction *transaction,
24252425

24262426
string_list_sort(&transaction->refnames);
24272427
if (ref_update_reject_duplicates(&transaction->refnames, err))
2428-
return TRANSACTION_GENERIC_ERROR;
2428+
return REF_TRANSACTION_ERROR_GENERIC;
24292429

24302430
ret = refs->be->transaction_prepare(refs, transaction, err);
24312431
if (ret)
@@ -2497,19 +2497,19 @@ int ref_transaction_commit(struct ref_transaction *transaction,
24972497
return ret;
24982498
}
24992499

2500-
int refs_verify_refnames_available(struct ref_store *refs,
2501-
const struct string_list *refnames,
2502-
const struct string_list *extras,
2503-
const struct string_list *skip,
2504-
unsigned int initial_transaction,
2505-
struct strbuf *err)
2500+
enum ref_transaction_error refs_verify_refnames_available(struct ref_store *refs,
2501+
const struct string_list *refnames,
2502+
const struct string_list *extras,
2503+
const struct string_list *skip,
2504+
unsigned int initial_transaction,
2505+
struct strbuf *err)
25062506
{
25072507
struct strbuf dirname = STRBUF_INIT;
25082508
struct strbuf referent = STRBUF_INIT;
25092509
struct string_list_item *item;
25102510
struct ref_iterator *iter = NULL;
25112511
struct strset dirnames;
2512-
int ret = -1;
2512+
int ret = REF_TRANSACTION_ERROR_NAME_CONFLICT;
25132513

25142514
/*
25152515
* For the sake of comments in this function, suppose that
@@ -2625,12 +2625,13 @@ int refs_verify_refnames_available(struct ref_store *refs,
26252625
return ret;
26262626
}
26272627

2628-
int refs_verify_refname_available(struct ref_store *refs,
2629-
const char *refname,
2630-
const struct string_list *extras,
2631-
const struct string_list *skip,
2632-
unsigned int initial_transaction,
2633-
struct strbuf *err)
2628+
enum ref_transaction_error refs_verify_refname_available(
2629+
struct ref_store *refs,
2630+
const char *refname,
2631+
const struct string_list *extras,
2632+
const struct string_list *skip,
2633+
unsigned int initial_transaction,
2634+
struct strbuf *err)
26342635
{
26352636
struct string_list_item item = { .string = (char *) refname };
26362637
struct string_list refnames = {
@@ -2818,26 +2819,28 @@ int ref_update_has_null_new_value(struct ref_update *update)
28182819
return !update->new_target && is_null_oid(&update->new_oid);
28192820
}
28202821

2821-
int ref_update_check_old_target(const char *referent, struct ref_update *update,
2822-
struct strbuf *err)
2822+
enum ref_transaction_error ref_update_check_old_target(const char *referent,
2823+
struct ref_update *update,
2824+
struct strbuf *err)
28232825
{
28242826
if (!update->old_target)
28252827
BUG("called without old_target set");
28262828

28272829
if (!strcmp(referent, update->old_target))
28282830
return 0;
28292831

2830-
if (!strcmp(referent, ""))
2832+
if (!strcmp(referent, "")) {
28312833
strbuf_addf(err, "verifying symref target: '%s': "
28322834
"reference is missing but expected %s",
28332835
ref_update_original_update_refname(update),
28342836
update->old_target);
2835-
else
2836-
strbuf_addf(err, "verifying symref target: '%s': "
2837-
"is at %s but expected %s",
2837+
return REF_TRANSACTION_ERROR_NONEXISTENT_REF;
2838+
}
2839+
2840+
strbuf_addf(err, "verifying symref target: '%s': is at %s but expected %s",
28382841
ref_update_original_update_refname(update),
28392842
referent, update->old_target);
2840-
return -1;
2843+
return REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE;
28412844
}
28422845

28432846
struct migration_data {

refs.h

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,23 @@ struct worktree;
1616
enum ref_storage_format ref_storage_format_by_name(const char *name);
1717
const char *ref_storage_format_to_name(enum ref_storage_format ref_storage_format);
1818

19+
enum ref_transaction_error {
20+
/* Default error code */
21+
REF_TRANSACTION_ERROR_GENERIC = -1,
22+
/* Ref name conflict like A vs A/B */
23+
REF_TRANSACTION_ERROR_NAME_CONFLICT = -2,
24+
/* Ref to be created already exists */
25+
REF_TRANSACTION_ERROR_CREATE_EXISTS = -3,
26+
/* ref expected but doesn't exist */
27+
REF_TRANSACTION_ERROR_NONEXISTENT_REF = -4,
28+
/* Provided old_oid or old_target of reference doesn't match actual */
29+
REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE = -5,
30+
/* Provided new_oid or new_target is invalid */
31+
REF_TRANSACTION_ERROR_INVALID_NEW_VALUE = -6,
32+
/* Expected ref to be symref, but is a regular ref */
33+
REF_TRANSACTION_ERROR_EXPECTED_SYMREF = -7,
34+
};
35+
1936
/*
2037
* Resolve a reference, recursively following symbolic references.
2138
*
@@ -117,24 +134,24 @@ int refs_read_symbolic_ref(struct ref_store *ref_store, const char *refname,
117134
*
118135
* extras and skip must be sorted.
119136
*/
120-
int refs_verify_refname_available(struct ref_store *refs,
121-
const char *refname,
122-
const struct string_list *extras,
123-
const struct string_list *skip,
124-
unsigned int initial_transaction,
125-
struct strbuf *err);
137+
enum ref_transaction_error refs_verify_refname_available(struct ref_store *refs,
138+
const char *refname,
139+
const struct string_list *extras,
140+
const struct string_list *skip,
141+
unsigned int initial_transaction,
142+
struct strbuf *err);
126143

127144
/*
128145
* Same as `refs_verify_refname_available()`, but checking for a list of
129146
* refnames instead of only a single item. This is more efficient in the case
130147
* where one needs to check multiple refnames.
131148
*/
132-
int refs_verify_refnames_available(struct ref_store *refs,
133-
const struct string_list *refnames,
134-
const struct string_list *extras,
135-
const struct string_list *skip,
136-
unsigned int initial_transaction,
137-
struct strbuf *err);
149+
enum ref_transaction_error refs_verify_refnames_available(struct ref_store *refs,
150+
const struct string_list *refnames,
151+
const struct string_list *extras,
152+
const struct string_list *skip,
153+
unsigned int initial_transaction,
154+
struct strbuf *err);
138155

139156
int refs_ref_exists(struct ref_store *refs, const char *refname);
140157

@@ -830,13 +847,6 @@ int ref_transaction_verify(struct ref_transaction *transaction,
830847
unsigned int flags,
831848
struct strbuf *err);
832849

833-
/* Naming conflict (for example, the ref names A and A/B conflict). */
834-
#define TRANSACTION_NAME_CONFLICT -1
835-
/* When only creation was requested, but the ref already exists. */
836-
#define TRANSACTION_CREATE_EXISTS -2
837-
/* All other errors. */
838-
#define TRANSACTION_GENERIC_ERROR -3
839-
840850
/*
841851
* Perform the preparatory stages of committing `transaction`. Acquire
842852
* any needed locks, check preconditions, etc.; basically, do as much

0 commit comments

Comments
 (0)