diff options
author | Patrick Steinhardt <ps@pks.im> | 2024-11-20 08:51:32 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2024-11-20 23:59:15 +0100 |
commit | 1c299d03e5551847533019aa32863d2cbe589c7f (patch) | |
tree | 5c0eacf60579bbb85c2d25acd1e48afb504e7b49 /refs.h | |
parent | refs/files: move logic to commit initial transaction (diff) | |
download | git-1c299d03e5551847533019aa32863d2cbe589c7f.tar.xz git-1c299d03e5551847533019aa32863d2cbe589c7f.zip |
refs: introduce "initial" transaction flag
There are two different ways to commit a transaction:
- `ref_transaction_commit()` can be used to commit a regular
transaction and is what almost every caller wants.
- `initial_ref_transaction_commit()` can be used when it is known that
the ref store that the transaction is committed for is empty and
when there are no concurrent processes. This is used when cloning a
new repository.
Implementing this via two separate functions has a couple of downsides.
First, every reference backend needs to implement a separate callback
even in the case where they don't special-case the initial transaction.
Second, backends are basically forced to reimplement the whole logic for
how to commit the transaction like the "files" backend does, even though
backends may wish to only tweak certain behaviour of a "normal" commit.
Third, it is awkward that callers must never prepare the transaction as
this is somewhat different than how a transaction typically works.
Refactor the code such that we instead mark initial transactions via a
separate flag when starting the transaction. This addresses all of the
mentioned painpoints, where the most important part is that it will
allow backends to have way more leeway in how exactly they want to
handle the initial transaction.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs.h')
-rw-r--r-- | refs.h | 37 |
1 files changed, 18 insertions, 19 deletions
@@ -214,11 +214,9 @@ char *repo_default_branch_name(struct repository *r, int quiet); * * Or * - * - Call `initial_ref_transaction_commit()` if the ref database is - * known to be empty and have no other writers (e.g. during - * clone). This is likely to be much faster than - * `ref_transaction_commit()`. `ref_transaction_prepare()` should - * *not* be called before `initial_ref_transaction_commit()`. + * - Call `ref_transaction_begin()` with REF_TRANSACTION_FLAG_INITIAL if the + * ref database is known to be empty and have no other writers (e.g. during + * clone). This is likely to be much faster than without the flag. * * - Then finally, call `ref_transaction_free()` to free the * `ref_transaction` data structure. @@ -579,6 +577,21 @@ enum action_on_err { UPDATE_REFS_QUIET_ON_ERR }; +enum ref_transaction_flag { + /* + * The ref transaction is part of the initial creation of the ref store + * and can thus assume that the ref store is completely empty. This + * allows the backend to perform the transaction more efficiently by + * skipping certain checks. + * + * It is a bug to set this flag when there might be other processes + * accessing the repository or if there are existing references that + * might conflict with the ones being created. All old_oid values must + * either be absent or null_oid. + */ + REF_TRANSACTION_FLAG_INITIAL = (1 << 0), +}; + /* * Begin a reference transaction. The reference transaction must * be freed by calling ref_transaction_free(). @@ -799,20 +812,6 @@ int ref_transaction_abort(struct ref_transaction *transaction, struct strbuf *err); /* - * Like ref_transaction_commit(), but optimized for creating - * references when originally initializing a repository (e.g., by "git - * clone"). It writes the new references directly to packed-refs - * without locking the individual references. - * - * It is a bug to call this function when there might be other - * processes accessing the repository or if there are existing - * references that might conflict with the ones being created. All - * old_oid values must either be absent or null_oid. - */ -int initial_ref_transaction_commit(struct ref_transaction *transaction, - struct strbuf *err); - -/* * Execute the given callback function for each of the reference updates which * have been queued in the given transaction. `old_oid` and `new_oid` may be * `NULL` pointers depending on whether the update has these object IDs set or |