Merge branch 'kn/non-transactional-batch-updates'
Updating multiple references have only been possible in all-or-none fashion with transactions, but it can be more efficient to batch multiple updates even when some of them are allowed to fail in a best-effort manner. A new "best effort batches of updates" mode has been introduced. * kn/non-transactional-batch-updates: update-ref: add --batch-updates flag for stdin mode refs: support rejection in batch updates during F/D checks refs: implement batch reference update support refs: introduce enum-based transaction error types refs/reftable: extract code from the transaction preparation refs/files: remove duplicate duplicates check refs: move duplicate refname update check to generic layer refs/files: remove redundant check in split_symref_update()
This commit is contained in:
70
refs.h
70
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
|
||||
@@ -887,6 +892,21 @@ void ref_transaction_for_each_queued_update(struct ref_transaction *transaction,
|
||||
ref_transaction_for_each_queued_update_fn cb,
|
||||
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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user