aboutsummaryrefslogtreecommitdiffstats
path: root/refs.h
diff options
context:
space:
mode:
Diffstat (limited to 'refs.h')
-rw-r--r--refs.h70
1 files changed, 45 insertions, 25 deletions
diff --git a/refs.h b/refs.h
index 240e2d8537..46a6008e07 100644
--- a/refs.h
+++ b/refs.h
@@ -16,6 +16,23 @@ struct worktree;
enum ref_storage_format ref_storage_format_by_name(const char *name);
const char *ref_storage_format_to_name(enum ref_storage_format ref_storage_format);
+enum ref_transaction_error {
+ /* Default error code */
+ REF_TRANSACTION_ERROR_GENERIC = -1,
+ /* Ref name conflict like A vs A/B */
+ REF_TRANSACTION_ERROR_NAME_CONFLICT = -2,
+ /* Ref to be created already exists */
+ REF_TRANSACTION_ERROR_CREATE_EXISTS = -3,
+ /* ref expected but doesn't exist */
+ REF_TRANSACTION_ERROR_NONEXISTENT_REF = -4,
+ /* Provided old_oid or old_target of reference doesn't match actual */
+ REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE = -5,
+ /* Provided new_oid or new_target is invalid */
+ REF_TRANSACTION_ERROR_INVALID_NEW_VALUE = -6,
+ /* Expected ref to be symref, but is a regular ref */
+ REF_TRANSACTION_ERROR_EXPECTED_SYMREF = -7,
+};
+
/*
* Resolve a reference, recursively following symbolic references.
*
@@ -117,24 +134,12 @@ int refs_read_symbolic_ref(struct ref_store *ref_store, const char *refname,
*
* extras and skip must be sorted.
*/
-int refs_verify_refname_available(struct ref_store *refs,
- const char *refname,
- const struct string_list *extras,
- const struct string_list *skip,
- unsigned int initial_transaction,
- struct strbuf *err);
-
-/*
- * Same as `refs_verify_refname_available()`, but checking for a list of
- * refnames instead of only a single item. This is more efficient in the case
- * where one needs to check multiple refnames.
- */
-int refs_verify_refnames_available(struct ref_store *refs,
- const struct string_list *refnames,
- const struct string_list *extras,
- const struct string_list *skip,
- unsigned int initial_transaction,
- struct strbuf *err);
+enum ref_transaction_error refs_verify_refname_available(struct ref_store *refs,
+ const char *refname,
+ const struct string_list *extras,
+ const struct string_list *skip,
+ unsigned int initial_transaction,
+ struct strbuf *err);
int refs_ref_exists(struct ref_store *refs, const char *refname);
@@ -650,6 +655,13 @@ enum ref_transaction_flag {
* either be absent or null_oid.
*/
REF_TRANSACTION_FLAG_INITIAL = (1 << 0),
+
+ /*
+ * The transaction mechanism by default fails all updates if any conflict
+ * is detected. This flag allows transactions to partially apply updates
+ * while rejecting updates which do not match the expected state.
+ */
+ REF_TRANSACTION_ALLOW_FAILURE = (1 << 1),
};
/*
@@ -830,13 +842,6 @@ int ref_transaction_verify(struct ref_transaction *transaction,
unsigned int flags,
struct strbuf *err);
-/* 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 -3
-
/*
* Perform the preparatory stages of committing `transaction`. Acquire
* any needed locks, check preconditions, etc.; basically, do as much
@@ -888,6 +893,21 @@ void ref_transaction_for_each_queued_update(struct ref_transaction *transaction,
void *cb_data);
/*
+ * Execute the given callback function for each of the reference updates which
+ * have been rejected in the given transaction.
+ */
+typedef void ref_transaction_for_each_rejected_update_fn(const char *refname,
+ const struct object_id *old_oid,
+ const struct object_id *new_oid,
+ const char *old_target,
+ const char *new_target,
+ enum ref_transaction_error err,
+ void *cb_data);
+void ref_transaction_for_each_rejected_update(struct ref_transaction *transaction,
+ ref_transaction_for_each_rejected_update_fn cb,
+ void *cb_data);
+
+/*
* Free `*transaction` and all associated data.
*/
void ref_transaction_free(struct ref_transaction *transaction);