Skip to content

Commit d21d296

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 partial transaction support. Signed-off-by: Karthik Nayak <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5e33e99 commit d21d296

File tree

7 files changed

+213
-186
lines changed

7 files changed

+213
-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,18 +2497,18 @@ 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 ref_iterator *iter = NULL;
25102510
struct strset dirnames;
2511-
int ret = -1;
2511+
int ret = REF_TRANSACTION_ERROR_NAME_CONFLICT;
25122512

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

2627-
int refs_verify_refname_available(struct ref_store *refs,
2628-
const char *refname,
2629-
const struct string_list *extras,
2630-
const struct string_list *skip,
2631-
unsigned int initial_transaction,
2632-
struct strbuf *err)
2627+
enum ref_transaction_error refs_verify_refname_available(
2628+
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)
26332634
{
26342635
struct string_list_item item = { .string = (char *) refname };
26352636
struct string_list refnames = {
@@ -2817,26 +2818,28 @@ int ref_update_has_null_new_value(struct ref_update *update)
28172818
return !update->new_target && is_null_oid(&update->new_oid);
28182819
}
28192820

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

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

2829-
if (!strcmp(referent, ""))
2831+
if (!strcmp(referent, "")) {
28302832
strbuf_addf(err, "verifying symref target: '%s': "
28312833
"reference is missing but expected %s",
28322834
ref_update_original_update_refname(update),
28332835
update->old_target);
2834-
else
2835-
strbuf_addf(err, "verifying symref target: '%s': "
2836-
"is at %s but expected %s",
2836+
return REF_TRANSACTION_ERROR_NONEXISTENT_REF;
2837+
}
2838+
2839+
strbuf_addf(err, "verifying symref target: '%s': is at %s but expected %s",
28372840
ref_update_original_update_refname(update),
28382841
referent, update->old_target);
2839-
return -1;
2842+
return REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE;
28402843
}
28412844

28422845
struct migration_data {

refs.h

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,29 @@ 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+
/*
20+
* enum ref_transaction_error represents the following return codes:
21+
* REF_TRANSACTION_ERROR_GENERIC error_code: default error code.
22+
* REF_TRANSACTION_ERROR_NAME_CONFLICT error_code: ref name conflict like A vs A/B.
23+
* REF_TRANSACTION_ERROR_CREATE_EXISTS error_code: ref to be created already exists.
24+
* REF_TRANSACTION_ERROR_NONEXISTENT_REF error_code: ref expected but doesn't exist.
25+
* REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE error_code: provided old_oid or old_target of
26+
* reference doesn't match actual.
27+
* REF_TRANSACTION_ERROR_INVALID_NEW_VALUE error_code: provided new_oid or new_target is
28+
* invalid.
29+
* REF_TRANSACTION_ERROR_EXPECTED_SYMREF error_code: expected ref to be symref, but is a
30+
* regular ref.
31+
*/
32+
enum ref_transaction_error {
33+
REF_TRANSACTION_ERROR_GENERIC = -1,
34+
REF_TRANSACTION_ERROR_NAME_CONFLICT = -2,
35+
REF_TRANSACTION_ERROR_CREATE_EXISTS = -3,
36+
REF_TRANSACTION_ERROR_NONEXISTENT_REF = -4,
37+
REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE = -5,
38+
REF_TRANSACTION_ERROR_INVALID_NEW_VALUE = -6,
39+
REF_TRANSACTION_ERROR_EXPECTED_SYMREF = -7,
40+
};
41+
1942
/*
2043
* Resolve a reference, recursively following symbolic references.
2144
*
@@ -117,24 +140,24 @@ int refs_read_symbolic_ref(struct ref_store *ref_store, const char *refname,
117140
*
118141
* extras and skip must be sorted.
119142
*/
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);
143+
enum ref_transaction_error refs_verify_refname_available(struct ref_store *refs,
144+
const char *refname,
145+
const struct string_list *extras,
146+
const struct string_list *skip,
147+
unsigned int initial_transaction,
148+
struct strbuf *err);
126149

127150
/*
128151
* Same as `refs_verify_refname_available()`, but checking for a list of
129152
* refnames instead of only a single item. This is more efficient in the case
130153
* where one needs to check multiple refnames.
131154
*/
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);
155+
enum ref_transaction_error refs_verify_refnames_available(struct ref_store *refs,
156+
const struct string_list *refnames,
157+
const struct string_list *extras,
158+
const struct string_list *skip,
159+
unsigned int initial_transaction,
160+
struct strbuf *err);
138161

139162
int refs_ref_exists(struct ref_store *refs, const char *refname);
140163

@@ -830,13 +853,6 @@ int ref_transaction_verify(struct ref_transaction *transaction,
830853
unsigned int flags,
831854
struct strbuf *err);
832855

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-
840856
/*
841857
* Perform the preparatory stages of committing `transaction`. Acquire
842858
* any needed locks, check preconditions, etc.; basically, do as much

0 commit comments

Comments
 (0)