Skip to content

Commit 1c299d0

Browse files
pks-tgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 83b8ed8 commit 1c299d0

File tree

8 files changed

+29
-68
lines changed

8 files changed

+29
-68
lines changed

builtin/clone.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ static void write_remote_refs(const struct ref *local_refs)
574574
struct strbuf err = STRBUF_INIT;
575575

576576
t = ref_store_transaction_begin(get_main_ref_store(the_repository),
577-
0, &err);
577+
REF_TRANSACTION_FLAG_INITIAL, &err);
578578
if (!t)
579579
die("%s", err.buf);
580580

@@ -586,7 +586,7 @@ static void write_remote_refs(const struct ref *local_refs)
586586
die("%s", err.buf);
587587
}
588588

589-
if (initial_ref_transaction_commit(t, &err))
589+
if (ref_transaction_commit(t, &err))
590590
die("%s", err.buf);
591591

592592
strbuf_release(&err);

refs.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2315,7 +2315,7 @@ int ref_transaction_commit(struct ref_transaction *transaction,
23152315
}
23162316

23172317
ret = refs->be->transaction_finish(refs, transaction, err);
2318-
if (!ret)
2318+
if (!ret && !(transaction->flags & REF_TRANSACTION_FLAG_INITIAL))
23192319
run_transaction_hook(transaction, "committed");
23202320
return ret;
23212321
}
@@ -2486,14 +2486,6 @@ int refs_reflog_expire(struct ref_store *refs,
24862486
cleanup_fn, policy_cb_data);
24872487
}
24882488

2489-
int initial_ref_transaction_commit(struct ref_transaction *transaction,
2490-
struct strbuf *err)
2491-
{
2492-
struct ref_store *refs = transaction->ref_store;
2493-
2494-
return refs->be->initial_transaction_commit(refs, transaction, err);
2495-
}
2496-
24972489
void ref_transaction_for_each_queued_update(struct ref_transaction *transaction,
24982490
ref_transaction_for_each_queued_update_fn cb,
24992491
void *cb_data)

refs.h

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,9 @@ char *repo_default_branch_name(struct repository *r, int quiet);
214214
*
215215
* Or
216216
*
217-
* - Call `initial_ref_transaction_commit()` if the ref database is
218-
* known to be empty and have no other writers (e.g. during
219-
* clone). This is likely to be much faster than
220-
* `ref_transaction_commit()`. `ref_transaction_prepare()` should
221-
* *not* be called before `initial_ref_transaction_commit()`.
217+
* - Call `ref_transaction_begin()` with REF_TRANSACTION_FLAG_INITIAL if the
218+
* ref database is known to be empty and have no other writers (e.g. during
219+
* clone). This is likely to be much faster than without the flag.
222220
*
223221
* - Then finally, call `ref_transaction_free()` to free the
224222
* `ref_transaction` data structure.
@@ -579,6 +577,21 @@ enum action_on_err {
579577
UPDATE_REFS_QUIET_ON_ERR
580578
};
581579

580+
enum ref_transaction_flag {
581+
/*
582+
* The ref transaction is part of the initial creation of the ref store
583+
* and can thus assume that the ref store is completely empty. This
584+
* allows the backend to perform the transaction more efficiently by
585+
* skipping certain checks.
586+
*
587+
* It is a bug to set this flag when there might be other processes
588+
* accessing the repository or if there are existing references that
589+
* might conflict with the ones being created. All old_oid values must
590+
* either be absent or null_oid.
591+
*/
592+
REF_TRANSACTION_FLAG_INITIAL = (1 << 0),
593+
};
594+
582595
/*
583596
* Begin a reference transaction. The reference transaction must
584597
* be freed by calling ref_transaction_free().
@@ -798,20 +811,6 @@ int ref_transaction_commit(struct ref_transaction *transaction,
798811
int ref_transaction_abort(struct ref_transaction *transaction,
799812
struct strbuf *err);
800813

801-
/*
802-
* Like ref_transaction_commit(), but optimized for creating
803-
* references when originally initializing a repository (e.g., by "git
804-
* clone"). It writes the new references directly to packed-refs
805-
* without locking the individual references.
806-
*
807-
* It is a bug to call this function when there might be other
808-
* processes accessing the repository or if there are existing
809-
* references that might conflict with the ones being created. All
810-
* old_oid values must either be absent or null_oid.
811-
*/
812-
int initial_ref_transaction_commit(struct ref_transaction *transaction,
813-
struct strbuf *err);
814-
815814
/*
816815
* Execute the given callback function for each of the reference updates which
817816
* have been queued in the given transaction. `old_oid` and `new_oid` may be

refs/debug.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -118,18 +118,6 @@ static int debug_transaction_abort(struct ref_store *refs,
118118
return res;
119119
}
120120

121-
static int debug_initial_transaction_commit(struct ref_store *refs,
122-
struct ref_transaction *transaction,
123-
struct strbuf *err)
124-
{
125-
struct debug_ref_store *drefs = (struct debug_ref_store *)refs;
126-
int res;
127-
transaction->ref_store = drefs->refs;
128-
res = drefs->refs->be->initial_transaction_commit(drefs->refs,
129-
transaction, err);
130-
return res;
131-
}
132-
133121
static int debug_pack_refs(struct ref_store *ref_store, struct pack_refs_opts *opts)
134122
{
135123
struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
@@ -443,7 +431,6 @@ struct ref_storage_be refs_be_debug = {
443431
.transaction_prepare = debug_transaction_prepare,
444432
.transaction_finish = debug_transaction_finish,
445433
.transaction_abort = debug_transaction_abort,
446-
.initial_transaction_commit = debug_initial_transaction_commit,
447434

448435
.pack_refs = debug_pack_refs,
449436
.rename_ref = debug_rename_ref,

refs/files-backend.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2781,6 +2781,8 @@ static int files_transaction_prepare(struct ref_store *ref_store,
27812781

27822782
assert(err);
27832783

2784+
if (transaction->flags & REF_TRANSACTION_FLAG_INITIAL)
2785+
goto cleanup;
27842786
if (!transaction->nr)
27852787
goto cleanup;
27862788

@@ -2985,22 +2987,19 @@ static int ref_present(const char *refname, const char *referent UNUSED,
29852987
return string_list_has_string(affected_refnames, refname);
29862988
}
29872989

2988-
static int files_initial_transaction_commit(struct ref_store *ref_store,
2990+
static int files_transaction_finish_initial(struct files_ref_store *refs,
29892991
struct ref_transaction *transaction,
29902992
struct strbuf *err)
29912993
{
2992-
struct files_ref_store *refs =
2993-
files_downcast(ref_store, REF_STORE_WRITE,
2994-
"initial_ref_transaction_commit");
29952994
size_t i;
29962995
int ret = 0;
29972996
struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
29982997
struct ref_transaction *packed_transaction = NULL;
29992998

30002999
assert(err);
30013000

3002-
if (transaction->state != REF_TRANSACTION_OPEN)
3003-
BUG("commit called for transaction that is not open");
3001+
if (transaction->state != REF_TRANSACTION_PREPARED)
3002+
BUG("commit called for transaction that is not prepared");
30043003

30053004
/* Fail if a refname appears more than once in the transaction: */
30063005
for (i = 0; i < transaction->nr; i++)
@@ -3063,7 +3062,7 @@ static int files_initial_transaction_commit(struct ref_store *ref_store,
30633062
goto cleanup;
30643063
}
30653064

3066-
if (initial_ref_transaction_commit(packed_transaction, err)) {
3065+
if (ref_transaction_commit(packed_transaction, err)) {
30673066
ret = TRANSACTION_GENERIC_ERROR;
30683067
}
30693068

@@ -3091,6 +3090,8 @@ static int files_transaction_finish(struct ref_store *ref_store,
30913090

30923091
assert(err);
30933092

3093+
if (transaction->flags & REF_TRANSACTION_FLAG_INITIAL)
3094+
return files_transaction_finish_initial(refs, transaction, err);
30943095
if (!transaction->nr) {
30953096
transaction->state = REF_TRANSACTION_CLOSED;
30963097
return 0;
@@ -3617,7 +3618,6 @@ struct ref_storage_be refs_be_files = {
36173618
.transaction_prepare = files_transaction_prepare,
36183619
.transaction_finish = files_transaction_finish,
36193620
.transaction_abort = files_transaction_abort,
3620-
.initial_transaction_commit = files_initial_transaction_commit,
36213621

36223622
.pack_refs = files_pack_refs,
36233623
.rename_ref = files_rename_ref,

refs/packed-backend.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,13 +1730,6 @@ static int packed_transaction_finish(struct ref_store *ref_store,
17301730
return ret;
17311731
}
17321732

1733-
static int packed_initial_transaction_commit(struct ref_store *ref_store UNUSED,
1734-
struct ref_transaction *transaction,
1735-
struct strbuf *err)
1736-
{
1737-
return ref_transaction_commit(transaction, err);
1738-
}
1739-
17401733
static int packed_pack_refs(struct ref_store *ref_store UNUSED,
17411734
struct pack_refs_opts *pack_opts UNUSED)
17421735
{
@@ -1769,7 +1762,6 @@ struct ref_storage_be refs_be_packed = {
17691762
.transaction_prepare = packed_transaction_prepare,
17701763
.transaction_finish = packed_transaction_finish,
17711764
.transaction_abort = packed_transaction_abort,
1772-
.initial_transaction_commit = packed_initial_transaction_commit,
17731765

17741766
.pack_refs = packed_pack_refs,
17751767
.rename_ref = NULL,

refs/refs-internal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,6 @@ struct ref_storage_be {
666666
ref_transaction_prepare_fn *transaction_prepare;
667667
ref_transaction_finish_fn *transaction_finish;
668668
ref_transaction_abort_fn *transaction_abort;
669-
ref_transaction_commit_fn *initial_transaction_commit;
670669

671670
pack_refs_fn *pack_refs;
672671
rename_ref_fn *rename_ref;

refs/reftable-backend.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,13 +1490,6 @@ static int reftable_be_transaction_finish(struct ref_store *ref_store UNUSED,
14901490
return ret;
14911491
}
14921492

1493-
static int reftable_be_initial_transaction_commit(struct ref_store *ref_store UNUSED,
1494-
struct ref_transaction *transaction,
1495-
struct strbuf *err)
1496-
{
1497-
return ref_transaction_commit(transaction, err);
1498-
}
1499-
15001493
static int reftable_be_pack_refs(struct ref_store *ref_store,
15011494
struct pack_refs_opts *opts)
15021495
{
@@ -2490,7 +2483,6 @@ struct ref_storage_be refs_be_reftable = {
24902483
.transaction_prepare = reftable_be_transaction_prepare,
24912484
.transaction_finish = reftable_be_transaction_finish,
24922485
.transaction_abort = reftable_be_transaction_abort,
2493-
.initial_transaction_commit = reftable_be_initial_transaction_commit,
24942486

24952487
.pack_refs = reftable_be_pack_refs,
24962488
.rename_ref = reftable_be_rename_ref,

0 commit comments

Comments
 (0)