2397
return 0;
2398
}
2399
2400
+struct files_transaction_backend_data {
2401
+ struct ref_transaction *packed_transaction;
2402
+ int packed_refs_locked;
2403
+};
2404
+
2405
/*
2406
* Unlock any references in `transaction` that are still locked, and
2407
* mark the transaction closed.
2408
*/
2404
-static void files_transaction_cleanup(struct ref_transaction *transaction)
2409
+static void files_transaction_cleanup(struct files_ref_store *refs,
2410
+ struct ref_transaction *transaction)
2411
{
2412
size_t i;
2413
+ struct files_transaction_backend_data *backend_data =
2414
+ transaction->backend_data;
2415
+ struct strbuf err = STRBUF_INIT;
2416
2417
for (i = 0; i < transaction->nr; i++) {
2418
struct ref_update *update = transaction->updates[i];
2424
}
2425
}
2426
2427
+ if (backend_data->packed_transaction &&
2428
+ ref_transaction_abort(backend_data->packed_transaction, &err)) {
2429
+ error("error aborting transaction: %s", err.buf);
2430
+ strbuf_release(&err);
2431
+ }
2432
+
2433
+ if (backend_data->packed_refs_locked)
2434
+ packed_refs_unlock(refs->packed_ref_store);
2435
+
2436
+ free(backend_data);
2437
+
2438
transaction->state = REF_TRANSACTION_CLOSED;
2439
}
2440
2451
char *head_ref = NULL;
2452
int head_type;
2453
struct object_id head_oid;
2454
+ struct files_transaction_backend_data *backend_data;
2455
+ struct ref_transaction *packed_transaction = NULL;
2456
2457
assert(err);
2458
2459
if (!transaction->nr)
2460
goto cleanup;
2461
2462
+ backend_data = xcalloc(1, sizeof(*backend_data));
2463
+ transaction->backend_data = backend_data;
2464
+
2465
/*
2466
* Fail if a refname appears more than once in the
2467
* transaction. (If we end up splitting up any updates using
2528
head_ref, &affected_refnames, err);
2529
if (ret)
2530
break;
2531
+
2532
+ if (update->flags & REF_DELETING &&
2533
+ !(update->flags & REF_LOG_ONLY) &&
2534
+ !(update->flags & REF_ISPRUNING)) {
2535
+ /*
2536
+ * This reference has to be deleted from
2537
+ * packed-refs if it exists there.
2538
+ */
2539
+ if (!packed_transaction) {
2540
+ packed_transaction = ref_store_transaction_begin(
2541
+ refs->packed_ref_store, err);
2542
+ if (!packed_transaction) {
2543
+ ret = TRANSACTION_GENERIC_ERROR;
2544
+ goto cleanup;
2545
+ }
2546
+
2547
+ backend_data->packed_transaction =
2548
+ packed_transaction;
2549
+ }
2550
+
2551
+ ref_transaction_add_update(
2552
+ packed_transaction, update->refname,
2553
+ update->flags & ~REF_HAVE_OLD,
2554
+ update->new_oid.hash, update->old_oid.hash,
2555
+ NULL);
2556
+ }
2557
+ }
2558
+
2559
+ if (packed_transaction) {
2560
+ if (packed_refs_lock(refs->packed_ref_store, 0, err)) {
2561
+ ret = TRANSACTION_GENERIC_ERROR;
2562
+ goto cleanup;
2563
+ }
2564
+ backend_data->packed_refs_locked = 1;
2565
+ ret = ref_transaction_prepare(packed_transaction, err);
2566
}
2567
2568
cleanup:
2570
string_list_clear(&affected_refnames, 0);
2571
2572
if (ret)
2513
- files_transaction_cleanup(transaction);
2573
+ files_transaction_cleanup(refs, transaction);
2574
else
2575
transaction->state = REF_TRANSACTION_PREPARED;
2576
2585
files_downcast(ref_store, 0, "ref_transaction_finish");
2586
size_t i;
2587
int ret = 0;
2528
- struct string_list refs_to_delete = STRING_LIST_INIT_NODUP;
2529
- struct string_list_item *ref_to_delete;
2588
struct strbuf sb = STRBUF_INIT;
2589
+ struct files_transaction_backend_data *backend_data;
2590
+ struct ref_transaction *packed_transaction;
2591
+
2592
2593
assert(err);
2594
2597
return 0;
2598
}
2599
2600
+ backend_data = transaction->backend_data;
2601
+ packed_transaction = backend_data->packed_transaction;
2602
+
2603
/* Perform updates first so live commits remain referenced */
2604
for (i = 0; i < transaction->nr; i++) {
2605
struct ref_update *update = transaction->updates[i];
2635
}
2636
}
2637
}
2574
- /* Perform deletes now that updates are safely completed */
2638
+
2639
+ /*
2640
+ * Perform deletes now that updates are safely completed.
2641
+ *
2642
+ * First delete any packed versions of the references, while
2643
+ * retaining the packed-refs lock:
2644
+ */
2645
+ if (packed_transaction) {
2646
+ ret = ref_transaction_commit(packed_transaction, err);
2647
+ ref_transaction_free(packed_transaction);
2648
+ packed_transaction = NULL;
2649
+ backend_data->packed_transaction = NULL;
2650
+ if (ret)
2651
+ goto cleanup;
2652
+ }
2653
+
2654
+ /* Now delete the loose versions of the references: */
2655
for (i = 0; i < transaction->nr; i++) {
2656
struct ref_update *update = transaction->updates[i];
2657
struct ref_lock *lock = update->backend_data;
2669
}
2670
update->flags |= REF_DELETED_LOOSE;
2671
}
2592
-
2593
- if (!(update->flags & REF_ISPRUNING))
2594
- string_list_append(&refs_to_delete,
2595
- lock->ref_name);
2672
}
2673
}
2674
2599
- if (packed_refs_lock(refs->packed_ref_store, 0, err)) {
2600
- ret = TRANSACTION_GENERIC_ERROR;
2601
- goto cleanup;
2602
- }
2603
-
2604
- if (repack_without_refs(refs->packed_ref_store, &refs_to_delete, err)) {
2605
- ret = TRANSACTION_GENERIC_ERROR;
2606
- packed_refs_unlock(refs->packed_ref_store);
2607
- goto cleanup;
2608
- }
2609
-
2610
- packed_refs_unlock(refs->packed_ref_store);
2611
-
2675
/* Delete the reflogs of any references that were deleted: */
2613
- for_each_string_list_item(ref_to_delete, &refs_to_delete) {
2614
- strbuf_reset(&sb);
2615
- files_reflog_path(refs, &sb, ref_to_delete->string);
2616
- if (!unlink_or_warn(sb.buf))
2617
- try_remove_empty_parents(refs, ref_to_delete->string,
2618
- REMOVE_EMPTY_PARENTS_REFLOG);
2676
+ for (i = 0; i < transaction->nr; i++) {
2677
+ struct ref_update *update = transaction->updates[i];
2678
+ if (update->flags & REF_DELETING &&
2679
+ !(update->flags & REF_LOG_ONLY) &&
2680
+ !(update->flags & REF_ISPRUNING)) {
2681
+ strbuf_reset(&sb);
2682
+ files_reflog_path(refs, &sb, update->refname);
2683
+ if (!unlink_or_warn(sb.buf))
2684
+ try_remove_empty_parents(refs, update->refname,
2685
+ REMOVE_EMPTY_PARENTS_REFLOG);
2686
+ }
2687
}
2688
2689
clear_loose_ref_cache(refs);
2690
2691
cleanup:
2624
- files_transaction_cleanup(transaction);
2692
+ files_transaction_cleanup(refs, transaction);
2693
2694
for (i = 0; i < transaction->nr; i++) {
2695
struct ref_update *update = transaction->updates[i];
2707
}
2708
2709
strbuf_release(&sb);
2642
- string_list_clear(&refs_to_delete, 0);
2710
return ret;
2711
}
2712
2714
struct ref_transaction *transaction,
2715
struct strbuf *err)
2716
{
2650
- files_transaction_cleanup(transaction);
2717
+ struct files_ref_store *refs =
2718
+ files_downcast(ref_store, 0, "ref_transaction_abort");
2719
+
2720
+ files_transaction_cleanup(refs, transaction);
2721
return 0;
2722
}
2723