]> git.ipfire.org Git - thirdparty/git.git/commitdiff
refs/files: move logic to commit initial transaction
authorPatrick Steinhardt <ps@pks.im>
Wed, 20 Nov 2024 07:51:31 +0000 (08:51 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 20 Nov 2024 22:59:15 +0000 (07:59 +0900)
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>
refs/files-backend.c

index df61057c9f24972b72644407cc95057891338d96..f37c805a34167b3749fbe724788180975abdae90 100644 (file)
@@ -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;