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>

Patrick Steinhardt committed Nov 20, 2024 at 08:51 UTC 83b8ed8bba5fe6655bb835a27b49bbf249314f55
1 file changed +101 -101
refs/files-backend.c
+101 -101
@@ -2975,6 +2975,107 @@ static int parse_and_write_reflog(struct files_ref_store *refs,
2975 return 0;
2976 }
2977
2978 +static int ref_present(const char *refname, const char *referent UNUSED,
2979 + const struct object_id *oid UNUSED,
2980 + int flags UNUSED,
2981 + void *cb_data)
2982 +{
2983 + struct string_list *affected_refnames = cb_data;
2984 +
2985 + return string_list_has_string(affected_refnames, refname);
2986 +}
2987 +
2988 +static int files_initial_transaction_commit(struct ref_store *ref_store,
2989 + struct ref_transaction *transaction,
2990 + struct strbuf *err)
2991 +{
2992 + struct files_ref_store *refs =
2993 + files_downcast(ref_store, REF_STORE_WRITE,
2994 + "initial_ref_transaction_commit");
2995 + size_t i;
2996 + int ret = 0;
2997 + struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
2998 + struct ref_transaction *packed_transaction = NULL;
2999 +
3000 + assert(err);
3001 +
3002 + if (transaction->state != REF_TRANSACTION_OPEN)
3003 + BUG("commit called for transaction that is not open");
3004 +
3005 + /* Fail if a refname appears more than once in the transaction: */
3006 + for (i = 0; i < transaction->nr; i++)
3007 + string_list_append(&affected_refnames,
3008 + transaction->updates[i]->refname);
3009 + string_list_sort(&affected_refnames);
3010 + if (ref_update_reject_duplicates(&affected_refnames, err)) {
3011 + ret = TRANSACTION_GENERIC_ERROR;
3012 + goto cleanup;
3013 + }
3014 +
3015 + /*
3016 + * It's really undefined to call this function in an active
3017 + * repository or when there are existing references: we are
3018 + * only locking and changing packed-refs, so (1) any
3019 + * simultaneous processes might try to change a reference at
3020 + * the same time we do, and (2) any existing loose versions of
3021 + * the references that we are setting would have precedence
3022 + * over our values. But some remote helpers create the remote
3023 + * "HEAD" and "master" branches before calling this function,
3024 + * so here we really only check that none of the references
3025 + * that we are creating already exists.
3026 + */
3027 + if (refs_for_each_rawref(&refs->base, ref_present,
3028 + &affected_refnames))
3029 + BUG("initial ref transaction called with existing refs");
3030 +
3031 + packed_transaction = ref_store_transaction_begin(refs->packed_ref_store,
3032 + transaction->flags, err);
3033 + if (!packed_transaction) {
3034 + ret = TRANSACTION_GENERIC_ERROR;
3035 + goto cleanup;
3036 + }
3037 +
3038 + for (i = 0; i < transaction->nr; i++) {
3039 + struct ref_update *update = transaction->updates[i];
3040 +
3041 + if ((update->flags & REF_HAVE_OLD) &&
3042 + !is_null_oid(&update->old_oid))
3043 + BUG("initial ref transaction with old_sha1 set");
3044 + if (refs_verify_refname_available(&refs->base, update->refname,
3045 + &affected_refnames, NULL,
3046 + err)) {
3047 + ret = TRANSACTION_NAME_CONFLICT;
3048 + goto cleanup;
3049 + }
3050 +
3051 + /*
3052 + * Add a reference creation for this reference to the
3053 + * packed-refs transaction:
3054 + */
3055 + ref_transaction_add_update(packed_transaction, update->refname,
3056 + update->flags & ~REF_HAVE_OLD,
3057 + &update->new_oid, &update->old_oid,
3058 + NULL, NULL, NULL);
3059 + }
3060 +
3061 + if (packed_refs_lock(refs->packed_ref_store, 0, err)) {
3062 + ret = TRANSACTION_GENERIC_ERROR;
3063 + goto cleanup;
3064 + }
3065 +
3066 + if (initial_ref_transaction_commit(packed_transaction, err)) {
3067 + ret = TRANSACTION_GENERIC_ERROR;
3068 + }
3069 +
3070 + packed_refs_unlock(refs->packed_ref_store);
3071 +cleanup:
3072 + if (packed_transaction)
3073 + ref_transaction_free(packed_transaction);
3074 + transaction->state = REF_TRANSACTION_CLOSED;
3075 + string_list_clear(&affected_refnames, 0);
3076 + return ret;
3077 +}
3078 +
3079 static int files_transaction_finish(struct ref_store *ref_store,
3080 struct ref_transaction *transaction,
3081 struct strbuf *err)
@@ -3123,107 +3224,6 @@ static int files_transaction_abort(struct ref_store *ref_store,
3224 return 0;
3225 }
3226
3126 -static int ref_present(const char *refname, const char *referent UNUSED,
3127 - const struct object_id *oid UNUSED,
3128 - int flags UNUSED,
3129 - void *cb_data)
3130 -{
3131 - struct string_list *affected_refnames = cb_data;
3132 -
3133 - return string_list_has_string(affected_refnames, refname);
3134 -}
3135 -
3136 -static int files_initial_transaction_commit(struct ref_store *ref_store,
3137 - struct ref_transaction *transaction,
3138 - struct strbuf *err)
3139 -{
3140 - struct files_ref_store *refs =
3141 - files_downcast(ref_store, REF_STORE_WRITE,
3142 - "initial_ref_transaction_commit");
3143 - size_t i;
3144 - int ret = 0;
3145 - struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
3146 - struct ref_transaction *packed_transaction = NULL;
3147 -
3148 - assert(err);
3149 -
3150 - if (transaction->state != REF_TRANSACTION_OPEN)
3151 - BUG("commit called for transaction that is not open");
3152 -
3153 - /* Fail if a refname appears more than once in the transaction: */
3154 - for (i = 0; i < transaction->nr; i++)
3155 - string_list_append(&affected_refnames,
3156 - transaction->updates[i]->refname);
3157 - string_list_sort(&affected_refnames);
3158 - if (ref_update_reject_duplicates(&affected_refnames, err)) {
3159 - ret = TRANSACTION_GENERIC_ERROR;
3160 - goto cleanup;
3161 - }
3162 -
3163 - /*
3164 - * It's really undefined to call this function in an active
3165 - * repository or when there are existing references: we are
3166 - * only locking and changing packed-refs, so (1) any
3167 - * simultaneous processes might try to change a reference at
3168 - * the same time we do, and (2) any existing loose versions of
3169 - * the references that we are setting would have precedence
3170 - * over our values. But some remote helpers create the remote
3171 - * "HEAD" and "master" branches before calling this function,
3172 - * so here we really only check that none of the references
3173 - * that we are creating already exists.
3174 - */
3175 - if (refs_for_each_rawref(&refs->base, ref_present,
3176 - &affected_refnames))
3177 - BUG("initial ref transaction called with existing refs");
3178 -
3179 - packed_transaction = ref_store_transaction_begin(refs->packed_ref_store,
3180 - transaction->flags, err);
3181 - if (!packed_transaction) {
3182 - ret = TRANSACTION_GENERIC_ERROR;
3183 - goto cleanup;
3184 - }
3185 -
3186 - for (i = 0; i < transaction->nr; i++) {
3187 - struct ref_update *update = transaction->updates[i];
3188 -
3189 - if ((update->flags & REF_HAVE_OLD) &&
3190 - !is_null_oid(&update->old_oid))
3191 - BUG("initial ref transaction with old_sha1 set");
3192 - if (refs_verify_refname_available(&refs->base, update->refname,
3193 - &affected_refnames, NULL,
3194 - err)) {
3195 - ret = TRANSACTION_NAME_CONFLICT;
3196 - goto cleanup;
3197 - }
3198 -
3199 - /*
3200 - * Add a reference creation for this reference to the
3201 - * packed-refs transaction:
3202 - */
3203 - ref_transaction_add_update(packed_transaction, update->refname,
3204 - update->flags & ~REF_HAVE_OLD,
3205 - &update->new_oid, &update->old_oid,
3206 - NULL, NULL, NULL);
3207 - }
3208 -
3209 - if (packed_refs_lock(refs->packed_ref_store, 0, err)) {
3210 - ret = TRANSACTION_GENERIC_ERROR;
3211 - goto cleanup;
3212 - }
3213 -
3214 - if (initial_ref_transaction_commit(packed_transaction, err)) {
3215 - ret = TRANSACTION_GENERIC_ERROR;
3216 - }
3217 -
3218 - packed_refs_unlock(refs->packed_ref_store);
3219 -cleanup:
3220 - if (packed_transaction)
3221 - ref_transaction_free(packed_transaction);
3222 - transaction->state = REF_TRANSACTION_CLOSED;
3223 - string_list_clear(&affected_refnames, 0);
3224 - return ret;
3225 -}
3226 -
3227 struct expire_reflog_cb {
3228 reflog_expiry_should_prune_fn *should_prune_fn;
3229 void *policy_cb;