reftable/stack: allow passing flags to `reftable_stack_add()`
The `reftable_stack_add()` function is a simple wrapper to lock the stack, add records to it via a callback and then commit the result. One problem with it though is that it doesn't accept any flags for creating the addition. This makes it impossible to automatically reload the stack in case it was modified before we managed to lock the stack. Add a `flags` field to plug this gap and pass it through accordingly. For now this new flag won't be used by us, but it will be used by libgit2. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Aug 12, 2025 at 11:54 UTC
178c5885007b83dd10cac1e09b72ef8d9fe2ac29
4 files changed
+39
-36
refs/reftable-backend.c
+4
-4
@@ -1960,7 +1960,7 @@ static int reftable_be_rename_ref(struct ref_store *ref_store,
1960
ret = backend_for(&arg.be, refs, newrefname, &newrefname, 1);
1961
if (ret)
1962
goto done;
1963
- ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg);
1963
+ ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg, 0);
1964
1965
done:
1966
assert(ret != REFTABLE_API_ERROR);
@@ -1989,7 +1989,7 @@ static int reftable_be_copy_ref(struct ref_store *ref_store,
1989
ret = backend_for(&arg.be, refs, newrefname, &newrefname, 1);
1990
if (ret)
1991
goto done;
1992
- ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg);
1992
+ ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg, 0);
1993
1994
done:
1995
assert(ret != REFTABLE_API_ERROR);
@@ -2360,7 +2360,7 @@ static int reftable_be_create_reflog(struct ref_store *ref_store,
2360
goto done;
2361
arg.stack = be->stack;
2362
2363
- ret = reftable_stack_add(be->stack, &write_reflog_existence_table, &arg);
2363
+ ret = reftable_stack_add(be->stack, &write_reflog_existence_table, &arg, 0);
2364
2365
done:
2366
return ret;
@@ -2431,7 +2431,7 @@ static int reftable_be_delete_reflog(struct ref_store *ref_store,
2431
return ret;
2432
arg.stack = be->stack;
2433
2434
- ret = reftable_stack_add(be->stack, &write_reflog_delete_table, &arg);
2434
+ ret = reftable_stack_add(be->stack, &write_reflog_delete_table, &arg, 0);
2435
2436
assert(ret != REFTABLE_API_ERROR);
2437
return ret;
reftable/reftable-stack.h
+6
-3
@@ -68,12 +68,15 @@ int reftable_addition_commit(struct reftable_addition *add);
68
* transaction. Releases the lock if held. */
69
void reftable_addition_destroy(struct reftable_addition *add);
70
71
-/* add a new table to the stack. The write_table function must call
72
- * reftable_writer_set_limits, add refs and return an error value. */
71
+/*
72
+ * Add a new table to the stack. The write_table function must call
73
+ * reftable_writer_set_limits, add refs and return an error value.
74
+ * The flags are passed through to `reftable_stack_new_addition()`.
75
+ */
76
int reftable_stack_add(struct reftable_stack *st,
77
int (*write_table)(struct reftable_writer *wr,
78
void *write_arg),
76
- void *write_arg);
79
+ void *write_arg, unsigned flags);
80
81
struct reftable_iterator;
82
reftable/stack.c
+4
-4
@@ -736,12 +736,12 @@ done:
736
static int stack_try_add(struct reftable_stack *st,
737
int (*write_table)(struct reftable_writer *wr,
738
void *arg),
739
- void *arg)
739
+ void *arg, unsigned flags)
740
{
741
struct reftable_addition add;
742
int err;
743
744
- err = reftable_stack_init_addition(&add, st, 0);
744
+ err = reftable_stack_init_addition(&add, st, flags);
745
if (err < 0)
746
goto done;
747
@@ -757,9 +757,9 @@ done:
757
758
int reftable_stack_add(struct reftable_stack *st,
759
int (*write)(struct reftable_writer *wr, void *arg),
760
- void *arg)
760
+ void *arg, unsigned flags)
761
{
762
- int err = stack_try_add(st, write, arg);
762
+ int err = stack_try_add(st, write, arg, flags);
763
if (err < 0) {
764
if (err == REFTABLE_OUTDATED_ERROR) {
765
/* Ignore error return, we want to propagate
t/unit-tests/t-reftable-stack.c
+25
-25
@@ -128,7 +128,7 @@ static void write_n_ref_tables(struct reftable_stack *st,
128
ref.refname = buf;
129
t_reftable_set_hash(ref.value.val1, i, REFTABLE_HASH_SHA1);
130
131
- err = reftable_stack_add(st, &write_test_ref, &ref);
131
+ err = reftable_stack_add(st, &write_test_ref, &ref, 0);
132
check(!err);
133
}
134
@@ -170,7 +170,7 @@ static void t_reftable_stack_add_one(void)
170
err = reftable_new_stack(&st, dir, &opts);
171
check(!err);
172
173
- err = reftable_stack_add(st, write_test_ref, &ref);
173
+ err = reftable_stack_add(st, write_test_ref, &ref, 0);
174
check(!err);
175
176
err = reftable_stack_read_ref(st, ref.refname, &dest);
@@ -235,16 +235,16 @@ static void t_reftable_stack_uptodate(void)
235
err = reftable_new_stack(&st2, dir, &opts);
236
check(!err);
237
238
- err = reftable_stack_add(st1, write_test_ref, &ref1);
238
+ err = reftable_stack_add(st1, write_test_ref, &ref1, 0);
239
check(!err);
240
241
- err = reftable_stack_add(st2, write_test_ref, &ref2);
241
+ err = reftable_stack_add(st2, write_test_ref, &ref2, 0);
242
check_int(err, ==, REFTABLE_OUTDATED_ERROR);
243
244
err = reftable_stack_reload(st2);
245
check(!err);
246
247
- err = reftable_stack_add(st2, write_test_ref, &ref2);
247
+ err = reftable_stack_add(st2, write_test_ref, &ref2, 0);
248
check(!err);
249
reftable_stack_destroy(st1);
250
reftable_stack_destroy(st2);
@@ -428,7 +428,7 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void)
428
err = reftable_new_stack(&st, dir, &opts);
429
check(!err);
430
431
- err = reftable_stack_add(st, write_test_ref, &ref);
431
+ err = reftable_stack_add(st, write_test_ref, &ref, 0);
432
check(!err);
433
check_int(st->merged->tables_len, ==, 1);
434
check_int(st->stats.attempts, ==, 0);
@@ -446,7 +446,7 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void)
446
write_file_buf(table_path.buf, "", 0);
447
448
ref.update_index = 2;
449
- err = reftable_stack_add(st, write_test_ref, &ref);
449
+ err = reftable_stack_add(st, write_test_ref, &ref, 0);
450
check(!err);
451
check_int(st->merged->tables_len, ==, 2);
452
check_int(st->stats.attempts, ==, 1);
@@ -484,10 +484,10 @@ static void t_reftable_stack_update_index_check(void)
484
err = reftable_new_stack(&st, dir, &opts);
485
check(!err);
486
487
- err = reftable_stack_add(st, write_test_ref, &ref1);
487
+ err = reftable_stack_add(st, write_test_ref, &ref1, 0);
488
check(!err);
489
490
- err = reftable_stack_add(st, write_test_ref, &ref2);
490
+ err = reftable_stack_add(st, write_test_ref, &ref2, 0);
491
check_int(err, ==, REFTABLE_API_ERROR);
492
reftable_stack_destroy(st);
493
clear_dir(dir);
@@ -503,7 +503,7 @@ static void t_reftable_stack_lock_failure(void)
503
err = reftable_new_stack(&st, dir, &opts);
504
check(!err);
505
for (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {
506
- err = reftable_stack_add(st, write_error, &i);
506
+ err = reftable_stack_add(st, write_error, &i, 0);
507
check_int(err, ==, i);
508
}
509
@@ -546,7 +546,7 @@ static void t_reftable_stack_add(void)
546
}
547
548
for (i = 0; i < N; i++) {
549
- int err = reftable_stack_add(st, write_test_ref, &refs[i]);
549
+ int err = reftable_stack_add(st, write_test_ref, &refs[i], 0);
550
check(!err);
551
}
552
@@ -555,7 +555,7 @@ static void t_reftable_stack_add(void)
555
.log = &logs[i],
556
.update_index = reftable_stack_next_update_index(st),
557
};
558
- int err = reftable_stack_add(st, write_test_log, &arg);
558
+ int err = reftable_stack_add(st, write_test_log, &arg, 0);
559
check(!err);
560
}
561
@@ -639,7 +639,7 @@ static void t_reftable_stack_iterator(void)
639
}
640
641
for (i = 0; i < N; i++) {
642
- err = reftable_stack_add(st, write_test_ref, &refs[i]);
642
+ err = reftable_stack_add(st, write_test_ref, &refs[i], 0);
643
check(!err);
644
}
645
@@ -649,7 +649,7 @@ static void t_reftable_stack_iterator(void)
649
.update_index = reftable_stack_next_update_index(st),
650
};
651
652
- err = reftable_stack_add(st, write_test_log, &arg);
652
+ err = reftable_stack_add(st, write_test_log, &arg, 0);
653
check(!err);
654
}
655
@@ -725,11 +725,11 @@ static void t_reftable_stack_log_normalize(void)
725
check(!err);
726
727
input.value.update.message = (char *) "one\ntwo";
728
- err = reftable_stack_add(st, write_test_log, &arg);
728
+ err = reftable_stack_add(st, write_test_log, &arg, 0);
729
check_int(err, ==, REFTABLE_API_ERROR);
730
731
input.value.update.message = (char *) "one";
732
- err = reftable_stack_add(st, write_test_log, &arg);
732
+ err = reftable_stack_add(st, write_test_log, &arg, 0);
733
check(!err);
734
735
err = reftable_stack_read_log(st, input.refname, &dest);
@@ -738,7 +738,7 @@ static void t_reftable_stack_log_normalize(void)
738
739
input.value.update.message = (char *) "two\n";
740
arg.update_index = 2;
741
- err = reftable_stack_add(st, write_test_log, &arg);
741
+ err = reftable_stack_add(st, write_test_log, &arg, 0);
742
check(!err);
743
err = reftable_stack_read_log(st, input.refname, &dest);
744
check(!err);
@@ -792,7 +792,7 @@ static void t_reftable_stack_tombstone(void)
792
}
793
}
794
for (i = 0; i < N; i++) {
795
- int err = reftable_stack_add(st, write_test_ref, &refs[i]);
795
+ int err = reftable_stack_add(st, write_test_ref, &refs[i], 0);
796
check(!err);
797
}
798
@@ -801,7 +801,7 @@ static void t_reftable_stack_tombstone(void)
801
.log = &logs[i],
802
.update_index = reftable_stack_next_update_index(st),
803
};
804
- int err = reftable_stack_add(st, write_test_log, &arg);
804
+ int err = reftable_stack_add(st, write_test_log, &arg, 0);
805
check(!err);
806
}
807
@@ -855,7 +855,7 @@ static void t_reftable_stack_hash_id(void)
855
err = reftable_new_stack(&st, dir, &opts);
856
check(!err);
857
858
- err = reftable_stack_add(st, write_test_ref, &ref);
858
+ err = reftable_stack_add(st, write_test_ref, &ref, 0);
859
check(!err);
860
861
/* can't read it with the wrong hash ID. */
@@ -927,7 +927,7 @@ static void t_reflog_expire(void)
927
.log = &logs[i],
928
.update_index = reftable_stack_next_update_index(st),
929
};
930
- int err = reftable_stack_add(st, write_test_log, &arg);
930
+ int err = reftable_stack_add(st, write_test_log, &arg, 0);
931
check(!err);
932
}
933
@@ -978,7 +978,7 @@ static void t_empty_add(void)
978
err = reftable_new_stack(&st, dir, &opts);
979
check(!err);
980
981
- err = reftable_stack_add(st, write_nothing, NULL);
981
+ err = reftable_stack_add(st, write_nothing, NULL, 0);
982
check(!err);
983
984
err = reftable_new_stack(&st2, dir, &opts);
@@ -1021,7 +1021,7 @@ static void t_reftable_stack_auto_compaction(void)
1021
};
1022
snprintf(name, sizeof(name), "branch%04"PRIuMAX, (uintmax_t)i);
1023
1024
- err = reftable_stack_add(st, write_test_ref, &ref);
1024
+ err = reftable_stack_add(st, write_test_ref, &ref, 0);
1025
check(!err);
1026
1027
err = reftable_stack_auto_compact(st);
@@ -1058,7 +1058,7 @@ static void t_reftable_stack_auto_compaction_factor(void)
1058
};
1059
xsnprintf(name, sizeof(name), "branch%04"PRIuMAX, (uintmax_t)i);
1060
1061
- err = reftable_stack_add(st, &write_test_ref, &ref);
1061
+ err = reftable_stack_add(st, &write_test_ref, &ref, 0);
1062
check(!err);
1063
1064
check(i < 5 || st->merged->tables_len < 5 * fastlogN(i, 5));
@@ -1140,7 +1140,7 @@ static void t_reftable_stack_add_performs_auto_compaction(void)
1140
snprintf(buf, sizeof(buf), "branch-%04"PRIuMAX, (uintmax_t)i);
1141
ref.refname = buf;
1142
1143
- err = reftable_stack_add(st, write_test_ref, &ref);
1143
+ err = reftable_stack_add(st, write_test_ref, &ref, 0);
1144
check(!err);
1145
1146
/*