refs/files: move logic to commit initial transaction
Move the logic to commit initial transactions such that we can start to call it in `files_transaction_finish()` in a subsequent commit without requiring a separate function declaration. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
a0efef1446
commit
83b8ed8bba
@ -2975,6 +2975,107 @@ static int parse_and_write_reflog(struct files_ref_store *refs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ref_present(const char *refname, const char *referent UNUSED,
|
||||
const struct object_id *oid UNUSED,
|
||||
int flags UNUSED,
|
||||
void *cb_data)
|
||||
{
|
||||
struct string_list *affected_refnames = cb_data;
|
||||
|
||||
return string_list_has_string(affected_refnames, refname);
|
||||
}
|
||||
|
||||
static int files_initial_transaction_commit(struct ref_store *ref_store,
|
||||
struct ref_transaction *transaction,
|
||||
struct strbuf *err)
|
||||
{
|
||||
struct files_ref_store *refs =
|
||||
files_downcast(ref_store, REF_STORE_WRITE,
|
||||
"initial_ref_transaction_commit");
|
||||
size_t i;
|
||||
int ret = 0;
|
||||
struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
|
||||
struct ref_transaction *packed_transaction = NULL;
|
||||
|
||||
assert(err);
|
||||
|
||||
if (transaction->state != REF_TRANSACTION_OPEN)
|
||||
BUG("commit called for transaction that is not open");
|
||||
|
||||
/* Fail if a refname appears more than once in the transaction: */
|
||||
for (i = 0; i < transaction->nr; i++)
|
||||
string_list_append(&affected_refnames,
|
||||
transaction->updates[i]->refname);
|
||||
string_list_sort(&affected_refnames);
|
||||
if (ref_update_reject_duplicates(&affected_refnames, err)) {
|
||||
ret = TRANSACTION_GENERIC_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* It's really undefined to call this function in an active
|
||||
* repository or when there are existing references: we are
|
||||
* only locking and changing packed-refs, so (1) any
|
||||
* simultaneous processes might try to change a reference at
|
||||
* the same time we do, and (2) any existing loose versions of
|
||||
* the references that we are setting would have precedence
|
||||
* over our values. But some remote helpers create the remote
|
||||
* "HEAD" and "master" branches before calling this function,
|
||||
* so here we really only check that none of the references
|
||||
* that we are creating already exists.
|
||||
*/
|
||||
if (refs_for_each_rawref(&refs->base, ref_present,
|
||||
&affected_refnames))
|
||||
BUG("initial ref transaction called with existing refs");
|
||||
|
||||
packed_transaction = ref_store_transaction_begin(refs->packed_ref_store,
|
||||
transaction->flags, err);
|
||||
if (!packed_transaction) {
|
||||
ret = TRANSACTION_GENERIC_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < transaction->nr; i++) {
|
||||
struct ref_update *update = transaction->updates[i];
|
||||
|
||||
if ((update->flags & REF_HAVE_OLD) &&
|
||||
!is_null_oid(&update->old_oid))
|
||||
BUG("initial ref transaction with old_sha1 set");
|
||||
if (refs_verify_refname_available(&refs->base, update->refname,
|
||||
&affected_refnames, NULL,
|
||||
err)) {
|
||||
ret = TRANSACTION_NAME_CONFLICT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a reference creation for this reference to the
|
||||
* packed-refs transaction:
|
||||
*/
|
||||
ref_transaction_add_update(packed_transaction, update->refname,
|
||||
update->flags & ~REF_HAVE_OLD,
|
||||
&update->new_oid, &update->old_oid,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (packed_refs_lock(refs->packed_ref_store, 0, err)) {
|
||||
ret = TRANSACTION_GENERIC_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (initial_ref_transaction_commit(packed_transaction, err)) {
|
||||
ret = TRANSACTION_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
packed_refs_unlock(refs->packed_ref_store);
|
||||
cleanup:
|
||||
if (packed_transaction)
|
||||
ref_transaction_free(packed_transaction);
|
||||
transaction->state = REF_TRANSACTION_CLOSED;
|
||||
string_list_clear(&affected_refnames, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int files_transaction_finish(struct ref_store *ref_store,
|
||||
struct ref_transaction *transaction,
|
||||
struct strbuf *err)
|
||||
@ -3123,107 +3224,6 @@ static int files_transaction_abort(struct ref_store *ref_store,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ref_present(const char *refname, const char *referent UNUSED,
|
||||
const struct object_id *oid UNUSED,
|
||||
int flags UNUSED,
|
||||
void *cb_data)
|
||||
{
|
||||
struct string_list *affected_refnames = cb_data;
|
||||
|
||||
return string_list_has_string(affected_refnames, refname);
|
||||
}
|
||||
|
||||
static int files_initial_transaction_commit(struct ref_store *ref_store,
|
||||
struct ref_transaction *transaction,
|
||||
struct strbuf *err)
|
||||
{
|
||||
struct files_ref_store *refs =
|
||||
files_downcast(ref_store, REF_STORE_WRITE,
|
||||
"initial_ref_transaction_commit");
|
||||
size_t i;
|
||||
int ret = 0;
|
||||
struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
|
||||
struct ref_transaction *packed_transaction = NULL;
|
||||
|
||||
assert(err);
|
||||
|
||||
if (transaction->state != REF_TRANSACTION_OPEN)
|
||||
BUG("commit called for transaction that is not open");
|
||||
|
||||
/* Fail if a refname appears more than once in the transaction: */
|
||||
for (i = 0; i < transaction->nr; i++)
|
||||
string_list_append(&affected_refnames,
|
||||
transaction->updates[i]->refname);
|
||||
string_list_sort(&affected_refnames);
|
||||
if (ref_update_reject_duplicates(&affected_refnames, err)) {
|
||||
ret = TRANSACTION_GENERIC_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* It's really undefined to call this function in an active
|
||||
* repository or when there are existing references: we are
|
||||
* only locking and changing packed-refs, so (1) any
|
||||
* simultaneous processes might try to change a reference at
|
||||
* the same time we do, and (2) any existing loose versions of
|
||||
* the references that we are setting would have precedence
|
||||
* over our values. But some remote helpers create the remote
|
||||
* "HEAD" and "master" branches before calling this function,
|
||||
* so here we really only check that none of the references
|
||||
* that we are creating already exists.
|
||||
*/
|
||||
if (refs_for_each_rawref(&refs->base, ref_present,
|
||||
&affected_refnames))
|
||||
BUG("initial ref transaction called with existing refs");
|
||||
|
||||
packed_transaction = ref_store_transaction_begin(refs->packed_ref_store,
|
||||
transaction->flags, err);
|
||||
if (!packed_transaction) {
|
||||
ret = TRANSACTION_GENERIC_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < transaction->nr; i++) {
|
||||
struct ref_update *update = transaction->updates[i];
|
||||
|
||||
if ((update->flags & REF_HAVE_OLD) &&
|
||||
!is_null_oid(&update->old_oid))
|
||||
BUG("initial ref transaction with old_sha1 set");
|
||||
if (refs_verify_refname_available(&refs->base, update->refname,
|
||||
&affected_refnames, NULL,
|
||||
err)) {
|
||||
ret = TRANSACTION_NAME_CONFLICT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a reference creation for this reference to the
|
||||
* packed-refs transaction:
|
||||
*/
|
||||
ref_transaction_add_update(packed_transaction, update->refname,
|
||||
update->flags & ~REF_HAVE_OLD,
|
||||
&update->new_oid, &update->old_oid,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (packed_refs_lock(refs->packed_ref_store, 0, err)) {
|
||||
ret = TRANSACTION_GENERIC_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (initial_ref_transaction_commit(packed_transaction, err)) {
|
||||
ret = TRANSACTION_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
packed_refs_unlock(refs->packed_ref_store);
|
||||
cleanup:
|
||||
if (packed_transaction)
|
||||
ref_transaction_free(packed_transaction);
|
||||
transaction->state = REF_TRANSACTION_CLOSED;
|
||||
string_list_clear(&affected_refnames, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct expire_reflog_cb {
|
||||
reflog_expiry_should_prune_fn *should_prune_fn;
|
||||
void *policy_cb;
|
||||
|
Reference in New Issue
Block a user