1
#define USE_THE_REPOSITORY_VARIABLE
3
#include "../git-compat-util.h"
5
#include "../chdir-notify.h"
8
#include "../environment.h"
12
#include "../iterator.h"
14
#include "../lockfile.h"
18
#include "../reftable/reftable-stack.h"
19
#include "../reftable/reftable-record.h"
20
#include "../reftable/reftable-error.h"
21
#include "../reftable/reftable-iterator.h"
25
#include "refs-internal.h"
31
#define REF_UPDATE_VIA_HEAD (1 << 8)
33
struct reftable_ref_store {
34
struct ref_store base;
40
struct reftable_stack *main_stack;
45
struct reftable_stack *worktree_stack;
50
struct strmap worktree_stacks;
51
struct reftable_write_options write_options;
53
unsigned int store_flags;
63
static struct reftable_ref_store *reftable_be_downcast(struct ref_store *ref_store,
64
unsigned int required_flags,
67
struct reftable_ref_store *refs;
69
if (ref_store->be != &refs_be_reftable)
70
BUG("ref_store is type \"%s\" not \"reftables\" in %s",
71
ref_store->be->name, caller);
73
refs = (struct reftable_ref_store *)ref_store;
75
if ((refs->store_flags & required_flags) != required_flags)
76
BUG("operation %s requires abilities 0x%x, but only have 0x%x",
77
caller, required_flags, refs->store_flags);
95
static struct reftable_stack *stack_for(struct reftable_ref_store *store,
97
const char **rewritten_ref)
103
return store->main_stack;
105
switch (parse_worktree_ref(refname, &wtname, &wtname_len, rewritten_ref)) {
106
case REF_WORKTREE_OTHER: {
107
static struct strbuf wtname_buf = STRBUF_INIT;
108
struct strbuf wt_dir = STRBUF_INIT;
109
struct reftable_stack *stack;
117
strbuf_reset(&wtname_buf);
118
strbuf_add(&wtname_buf, wtname, wtname_len);
129
stack = strmap_get(&store->worktree_stacks, wtname_buf.buf);
131
strbuf_addf(&wt_dir, "%s/worktrees/%s/reftable",
132
store->base.repo->commondir, wtname_buf.buf);
134
store->err = reftable_new_stack(&stack, wt_dir.buf,
135
&store->write_options);
136
assert(store->err != REFTABLE_API_ERROR);
137
strmap_put(&store->worktree_stacks, wtname_buf.buf, stack);
140
strbuf_release(&wt_dir);
143
case REF_WORKTREE_CURRENT:
148
if (!store->worktree_stack)
149
return store->main_stack;
150
return store->worktree_stack;
151
case REF_WORKTREE_MAIN:
152
case REF_WORKTREE_SHARED:
153
return store->main_stack;
155
BUG("unhandled worktree reference type");
159
static int should_write_log(struct ref_store *refs, const char *refname)
161
if (log_all_ref_updates == LOG_REFS_UNSET)
162
log_all_ref_updates = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL;
164
switch (log_all_ref_updates) {
166
return refs_reflog_exists(refs, refname);
167
case LOG_REFS_ALWAYS:
169
case LOG_REFS_NORMAL:
170
if (should_autocreate_reflog(refname))
172
return refs_reflog_exists(refs, refname);
174
BUG("unhandled core.logAllRefUpdates value %d", log_all_ref_updates);
178
static void fill_reftable_log_record(struct reftable_log_record *log, const struct ident_split *split)
180
const char *tz_begin;
183
reftable_log_record_release(log);
184
log->value_type = REFTABLE_LOG_UPDATE;
185
log->value.update.name =
186
xstrndup(split->name_begin, split->name_end - split->name_begin);
187
log->value.update.email =
188
xstrndup(split->mail_begin, split->mail_end - split->mail_begin);
189
log->value.update.time = atol(split->date_begin);
191
tz_begin = split->tz_begin;
192
if (*tz_begin == '-') {
196
if (*tz_begin == '+') {
201
log->value.update.tz_offset = sign * atoi(tz_begin);
204
static int read_ref_without_reload(struct reftable_ref_store *refs,
205
struct reftable_stack *stack,
207
struct object_id *oid,
208
struct strbuf *referent,
211
struct reftable_ref_record ref = {0};
214
ret = reftable_stack_read_ref(stack, refname, &ref);
218
if (ref.value_type == REFTABLE_REF_SYMREF) {
219
strbuf_reset(referent);
220
strbuf_addstr(referent, ref.value.symref);
221
*type |= REF_ISSYMREF;
222
} else if (reftable_ref_record_val1(&ref)) {
223
oidread(oid, reftable_ref_record_val1(&ref),
224
refs->base.repo->hash_algo);
227
BUG("unhandled reference value type %d", ref.value_type);
231
assert(ret != REFTABLE_API_ERROR);
232
reftable_ref_record_release(&ref);
236
static int reftable_be_config(const char *var, const char *value,
237
const struct config_context *ctx,
240
struct reftable_write_options *opts = _opts;
242
if (!strcmp(var, "reftable.blocksize")) {
243
unsigned long block_size = git_config_ulong(var, value, ctx->kvi);
244
if (block_size > 16777215)
245
die("reftable block size cannot exceed 16MB");
246
opts->block_size = block_size;
247
} else if (!strcmp(var, "reftable.restartinterval")) {
248
unsigned long restart_interval = git_config_ulong(var, value, ctx->kvi);
249
if (restart_interval > UINT16_MAX)
250
die("reftable block size cannot exceed %u", (unsigned)UINT16_MAX);
251
opts->restart_interval = restart_interval;
252
} else if (!strcmp(var, "reftable.indexobjects")) {
253
opts->skip_index_objects = !git_config_bool(var, value);
254
} else if (!strcmp(var, "reftable.geometricfactor")) {
255
unsigned long factor = git_config_ulong(var, value, ctx->kvi);
256
if (factor > UINT8_MAX)
257
die("reftable geometric factor cannot exceed %u", (unsigned)UINT8_MAX);
258
opts->auto_compaction_factor = factor;
264
static struct ref_store *reftable_be_init(struct repository *repo,
266
unsigned int store_flags)
268
struct reftable_ref_store *refs = xcalloc(1, sizeof(*refs));
269
struct strbuf path = STRBUF_INIT;
276
base_ref_store_init(&refs->base, repo, gitdir, &refs_be_reftable);
277
strmap_init(&refs->worktree_stacks);
278
refs->store_flags = store_flags;
280
refs->write_options.hash_id = repo->hash_algo->format_id;
281
refs->write_options.default_permissions = calc_shared_perm(0666 & ~mask);
282
refs->write_options.disable_auto_compact =
283
!git_env_bool("GIT_TEST_REFTABLE_AUTOCOMPACTION", 1);
285
git_config(reftable_be_config, &refs->write_options);
294
if (!refs->write_options.block_size)
295
refs->write_options.block_size = 4096;
304
is_worktree = get_common_dir_noenv(&path, gitdir);
307
strbuf_realpath(&path, gitdir, 0);
309
strbuf_addstr(&path, "/reftable");
310
refs->err = reftable_new_stack(&refs->main_stack, path.buf,
311
&refs->write_options);
325
strbuf_addf(&path, "%s/reftable", gitdir);
327
refs->err = reftable_new_stack(&refs->worktree_stack, path.buf,
328
&refs->write_options);
333
chdir_notify_reparent("reftables-backend $GIT_DIR", &refs->base.gitdir);
336
assert(refs->err != REFTABLE_API_ERROR);
337
strbuf_release(&path);
341
static void reftable_be_release(struct ref_store *ref_store)
343
struct reftable_ref_store *refs = reftable_be_downcast(ref_store, 0, "release");
344
struct strmap_entry *entry;
345
struct hashmap_iter iter;
347
if (refs->main_stack) {
348
reftable_stack_destroy(refs->main_stack);
349
refs->main_stack = NULL;
352
if (refs->worktree_stack) {
353
reftable_stack_destroy(refs->worktree_stack);
354
refs->worktree_stack = NULL;
357
strmap_for_each_entry(&refs->worktree_stacks, &iter, entry)
358
reftable_stack_destroy(entry->value);
359
strmap_clear(&refs->worktree_stacks, 0);
362
static int reftable_be_create_on_disk(struct ref_store *ref_store,
364
struct strbuf *err UNUSED)
366
struct reftable_ref_store *refs =
367
reftable_be_downcast(ref_store, REF_STORE_WRITE, "create");
368
struct strbuf sb = STRBUF_INIT;
370
strbuf_addf(&sb, "%s/reftable", refs->base.gitdir);
371
safe_create_dir(sb.buf, 1);
374
strbuf_addf(&sb, "%s/HEAD", refs->base.gitdir);
375
write_file(sb.buf, "ref: refs/heads/.invalid");
376
adjust_shared_perm(sb.buf);
379
strbuf_addf(&sb, "%s/refs", refs->base.gitdir);
380
safe_create_dir(sb.buf, 1);
383
strbuf_addf(&sb, "%s/refs/heads", refs->base.gitdir);
384
write_file(sb.buf, "this repository uses the reftable format");
385
adjust_shared_perm(sb.buf);
391
static int reftable_be_remove_on_disk(struct ref_store *ref_store,
394
struct reftable_ref_store *refs =
395
reftable_be_downcast(ref_store, REF_STORE_WRITE, "remove");
396
struct strbuf sb = STRBUF_INIT;
404
reftable_be_release(ref_store);
406
strbuf_addf(&sb, "%s/reftable", refs->base.gitdir);
407
if (remove_dir_recursively(&sb, 0) < 0) {
408
strbuf_addf(err, "could not delete reftables: %s",
414
strbuf_addf(&sb, "%s/HEAD", refs->base.gitdir);
415
if (unlink(sb.buf) < 0) {
416
strbuf_addf(err, "could not delete stub HEAD: %s",
422
strbuf_addf(&sb, "%s/refs/heads", refs->base.gitdir);
423
if (unlink(sb.buf) < 0) {
424
strbuf_addf(err, "could not delete stub heads: %s",
430
strbuf_addf(&sb, "%s/refs", refs->base.gitdir);
431
if (rmdir(sb.buf) < 0) {
432
strbuf_addf(err, "could not delete refs directory: %s",
441
struct reftable_ref_iterator {
442
struct ref_iterator base;
443
struct reftable_ref_store *refs;
444
struct reftable_iterator iter;
445
struct reftable_ref_record ref;
446
struct object_id oid;
454
static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
456
struct reftable_ref_iterator *iter =
457
(struct reftable_ref_iterator *)ref_iterator;
458
struct reftable_ref_store *refs = iter->refs;
459
const char *referent = NULL;
464
iter->err = reftable_iterator_next_ref(&iter->iter, &iter->ref);
472
if (!starts_with(iter->ref.refname, "refs/") &&
473
!(iter->flags & DO_FOR_EACH_INCLUDE_ROOT_REFS &&
474
is_root_ref(iter->ref.refname))) {
478
if (iter->prefix_len &&
479
strncmp(iter->prefix, iter->ref.refname, iter->prefix_len)) {
484
if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY &&
485
parse_worktree_ref(iter->ref.refname, NULL, NULL, NULL) !=
486
REF_WORKTREE_CURRENT)
489
switch (iter->ref.value_type) {
490
case REFTABLE_REF_VAL1:
491
oidread(&iter->oid, iter->ref.value.val1,
492
refs->base.repo->hash_algo);
494
case REFTABLE_REF_VAL2:
495
oidread(&iter->oid, iter->ref.value.val2.value,
496
refs->base.repo->hash_algo);
498
case REFTABLE_REF_SYMREF:
499
referent = refs_resolve_ref_unsafe(&iter->refs->base,
504
oidclr(&iter->oid, refs->base.repo->hash_algo);
507
BUG("unhandled reference value type %d", iter->ref.value_type);
510
if (is_null_oid(&iter->oid))
511
flags |= REF_ISBROKEN;
513
if (check_refname_format(iter->ref.refname, REFNAME_ALLOW_ONELEVEL)) {
514
if (!refname_is_safe(iter->ref.refname))
515
die(_("refname is dangerous: %s"), iter->ref.refname);
516
oidclr(&iter->oid, refs->base.repo->hash_algo);
517
flags |= REF_BAD_NAME | REF_ISBROKEN;
520
if (iter->flags & DO_FOR_EACH_OMIT_DANGLING_SYMREFS &&
521
flags & REF_ISSYMREF &&
522
flags & REF_ISBROKEN)
525
if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
526
!ref_resolves_to_object(iter->ref.refname, refs->base.repo,
530
iter->base.refname = iter->ref.refname;
531
iter->base.referent = referent;
532
iter->base.oid = &iter->oid;
533
iter->base.flags = flags;
539
if (ref_iterator_abort(ref_iterator) != ITER_DONE)
545
ref_iterator_abort(ref_iterator);
552
static int reftable_ref_iterator_peel(struct ref_iterator *ref_iterator,
553
struct object_id *peeled)
555
struct reftable_ref_iterator *iter =
556
(struct reftable_ref_iterator *)ref_iterator;
558
if (iter->ref.value_type == REFTABLE_REF_VAL2) {
559
oidread(peeled, iter->ref.value.val2.target_value,
560
iter->refs->base.repo->hash_algo);
567
static int reftable_ref_iterator_abort(struct ref_iterator *ref_iterator)
569
struct reftable_ref_iterator *iter =
570
(struct reftable_ref_iterator *)ref_iterator;
571
reftable_ref_record_release(&iter->ref);
572
reftable_iterator_destroy(&iter->iter);
577
static struct ref_iterator_vtable reftable_ref_iterator_vtable = {
578
.advance = reftable_ref_iterator_advance,
579
.peel = reftable_ref_iterator_peel,
580
.abort = reftable_ref_iterator_abort
583
static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_store *refs,
584
struct reftable_stack *stack,
588
struct reftable_ref_iterator *iter;
591
iter = xcalloc(1, sizeof(*iter));
592
base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable);
593
iter->prefix = prefix;
594
iter->prefix_len = prefix ? strlen(prefix) : 0;
595
iter->base.oid = &iter->oid;
603
ret = reftable_stack_reload(stack);
607
reftable_stack_init_ref_iterator(stack, &iter->iter);
608
ret = reftable_iterator_seek_ref(&iter->iter, prefix);
617
static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_store,
619
const char **exclude_patterns UNUSED,
622
struct reftable_ref_iterator *main_iter, *worktree_iter;
623
struct reftable_ref_store *refs;
624
unsigned int required_flags = REF_STORE_READ;
626
if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN))
627
required_flags |= REF_STORE_ODB;
628
refs = reftable_be_downcast(ref_store, required_flags, "ref_iterator_begin");
630
main_iter = ref_iterator_for_stack(refs, refs->main_stack, prefix, flags);
637
if (!refs->worktree_stack)
638
return &main_iter->base;
644
worktree_iter = ref_iterator_for_stack(refs, refs->worktree_stack, prefix, flags);
645
return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base,
646
ref_iterator_select, NULL);
649
static int reftable_be_read_raw_ref(struct ref_store *ref_store,
651
struct object_id *oid,
652
struct strbuf *referent,
656
struct reftable_ref_store *refs =
657
reftable_be_downcast(ref_store, REF_STORE_READ, "read_raw_ref");
658
struct reftable_stack *stack = stack_for(refs, refname, &refname);
664
ret = reftable_stack_reload(stack);
668
ret = read_ref_without_reload(refs, stack, refname, oid, referent, type);
672
*failure_errno = ENOENT;
679
static int reftable_be_read_symbolic_ref(struct ref_store *ref_store,
681
struct strbuf *referent)
683
struct reftable_ref_store *refs =
684
reftable_be_downcast(ref_store, REF_STORE_READ, "read_symbolic_ref");
685
struct reftable_stack *stack = stack_for(refs, refname, &refname);
686
struct reftable_ref_record ref = {0};
689
ret = reftable_stack_reload(stack);
693
ret = reftable_stack_read_ref(stack, refname, &ref);
694
if (ret == 0 && ref.value_type == REFTABLE_REF_SYMREF)
695
strbuf_addstr(referent, ref.value.symref);
699
reftable_ref_record_release(&ref);
703
struct reftable_transaction_update {
704
struct ref_update *update;
705
struct object_id current_oid;
708
struct write_transaction_table_arg {
709
struct reftable_ref_store *refs;
710
struct reftable_stack *stack;
711
struct reftable_addition *addition;
712
struct reftable_transaction_update *updates;
714
size_t updates_alloc;
715
size_t updates_expected;
718
struct reftable_transaction_data {
719
struct write_transaction_table_arg *args;
720
size_t args_nr, args_alloc;
723
static void free_transaction_data(struct reftable_transaction_data *tx_data)
727
for (size_t i = 0; i < tx_data->args_nr; i++) {
728
reftable_addition_destroy(tx_data->args[i].addition);
729
free(tx_data->args[i].updates);
739
static int prepare_transaction_update(struct write_transaction_table_arg **out,
740
struct reftable_ref_store *refs,
741
struct reftable_transaction_data *tx_data,
742
struct ref_update *update,
745
struct reftable_stack *stack = stack_for(refs, update->refname, NULL);
746
struct write_transaction_table_arg *arg = NULL;
754
for (i = 0; !arg && i < tx_data->args_nr; i++)
755
if (tx_data->args[i].stack == stack)
756
arg = &tx_data->args[i];
759
struct reftable_addition *addition;
761
ret = reftable_stack_reload(stack);
765
ret = reftable_stack_new_addition(&addition, stack);
767
if (ret == REFTABLE_LOCK_ERROR)
768
strbuf_addstr(err, "cannot lock references");
772
ALLOC_GROW(tx_data->args, tx_data->args_nr + 1,
773
tx_data->args_alloc);
774
arg = &tx_data->args[tx_data->args_nr++];
777
arg->addition = addition;
780
arg->updates_alloc = 0;
781
arg->updates_expected = 0;
784
arg->updates_expected++;
797
static int queue_transaction_update(struct reftable_ref_store *refs,
798
struct reftable_transaction_data *tx_data,
799
struct ref_update *update,
800
struct object_id *current_oid,
803
struct write_transaction_table_arg *arg = NULL;
806
if (update->backend_data)
807
BUG("reference update queued more than once");
809
ret = prepare_transaction_update(&arg, refs, tx_data, update, err);
813
ALLOC_GROW(arg->updates, arg->updates_nr + 1,
815
arg->updates[arg->updates_nr].update = update;
816
oidcpy(&arg->updates[arg->updates_nr].current_oid, current_oid);
817
update->backend_data = &arg->updates[arg->updates_nr++];
822
static int reftable_be_transaction_prepare(struct ref_store *ref_store,
823
struct ref_transaction *transaction,
826
struct reftable_ref_store *refs =
827
reftable_be_downcast(ref_store, REF_STORE_WRITE|REF_STORE_MAIN, "ref_transaction_prepare");
828
struct strbuf referent = STRBUF_INIT, head_referent = STRBUF_INIT;
829
struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
830
struct reftable_transaction_data *tx_data = NULL;
831
struct object_id head_oid;
832
unsigned int head_type = 0;
840
tx_data = xcalloc(1, sizeof(*tx_data));
847
for (i = 0; i < transaction->nr; i++) {
848
ret = prepare_transaction_update(NULL, refs, tx_data,
849
transaction->updates[i], err);
853
string_list_append(&affected_refnames,
854
transaction->updates[i]->refname);
861
for (i = 0; i < tx_data->args_nr; i++) {
862
CALLOC_ARRAY(tx_data->args[i].updates, tx_data->args[i].updates_expected);
863
tx_data->args[i].updates_alloc = tx_data->args[i].updates_expected;
871
string_list_sort(&affected_refnames);
872
if (ref_update_reject_duplicates(&affected_refnames, err)) {
873
ret = TRANSACTION_GENERIC_ERROR;
877
ret = read_ref_without_reload(refs, stack_for(refs, "HEAD", NULL), "HEAD",
878
&head_oid, &head_referent, &head_type);
883
for (i = 0; i < transaction->nr; i++) {
884
struct ref_update *u = transaction->updates[i];
885
struct object_id current_oid = {0};
886
struct reftable_stack *stack;
887
const char *rewritten_ref;
889
stack = stack_for(refs, u->refname, &rewritten_ref);
892
if ((u->flags & REF_HAVE_NEW) && !is_null_oid(&u->new_oid) &&
893
!(u->flags & REF_SKIP_OID_VERIFICATION) &&
894
!(u->flags & REF_LOG_ONLY)) {
895
struct object *o = parse_object(refs->base.repo, &u->new_oid);
898
_("trying to write ref '%s' with nonexistent object %s"),
899
u->refname, oid_to_hex(&u->new_oid));
904
if (o->type != OBJ_COMMIT && is_branch(u->refname)) {
905
strbuf_addf(err, _("trying to write non-commit object %s to branch '%s'"),
906
oid_to_hex(&u->new_oid), u->refname);
917
if (head_type == REF_ISSYMREF &&
918
!(u->flags & REF_LOG_ONLY) &&
919
!(u->flags & REF_UPDATE_VIA_HEAD) &&
920
!strcmp(rewritten_ref, head_referent.buf)) {
921
struct ref_update *new_update;
928
if (string_list_has_string(&affected_refnames, "HEAD")) {
931
_("multiple updates for 'HEAD' (including one "
932
"via its referent '%s') are not allowed"),
934
ret = TRANSACTION_NAME_CONFLICT;
938
new_update = ref_transaction_add_update(
940
u->flags | REF_LOG_ONLY | REF_NO_DEREF,
941
&u->new_oid, &u->old_oid, NULL, NULL, u->msg);
942
string_list_insert(&affected_refnames, new_update->refname);
945
ret = read_ref_without_reload(refs, stack, rewritten_ref,
946
¤t_oid, &referent, &u->type);
949
if (ret > 0 && !ref_update_expects_existing_old_ref(u)) {
959
ret = refs_verify_refname_available(ref_store, u->refname,
960
&affected_refnames, NULL, err);
968
if ((u->flags & REF_HAVE_NEW) && !ref_update_has_null_new_value(u)) {
969
ret = queue_transaction_update(refs, tx_data, u,
979
strbuf_addf(err, _("cannot lock ref '%s': "
980
"unable to resolve reference '%s'"),
981
ref_update_original_update_refname(u), u->refname);
986
if (u->type & REF_ISSYMREF) {
992
const char *resolved = refs_resolve_ref_unsafe(&refs->base, u->refname, 0,
995
if (u->flags & REF_NO_DEREF) {
996
if (u->flags & REF_HAVE_OLD && !resolved) {
997
strbuf_addf(err, _("cannot lock ref '%s': "
998
"error reading reference"), u->refname);
1003
struct ref_update *new_update;
1006
new_flags = u->flags;
1007
if (!strcmp(rewritten_ref, "HEAD"))
1008
new_flags |= REF_UPDATE_VIA_HEAD;
1018
new_update = ref_transaction_add_update(
1019
transaction, referent.buf, new_flags,
1020
u->new_target ? NULL : &u->new_oid,
1021
u->old_target ? NULL : &u->old_oid,
1022
u->new_target, u->old_target, u->msg);
1024
new_update->parent_update = u;
1031
u->flags |= REF_LOG_ONLY | REF_NO_DEREF;
1032
u->flags &= ~REF_HAVE_OLD;
1034
if (string_list_has_string(&affected_refnames, new_update->refname)) {
1036
_("multiple updates for '%s' (including one "
1037
"via symref '%s') are not allowed"),
1038
referent.buf, u->refname);
1039
ret = TRANSACTION_NAME_CONFLICT;
1042
string_list_insert(&affected_refnames, new_update->refname);
1053
if (u->old_target) {
1054
if (!(u->type & REF_ISSYMREF)) {
1055
strbuf_addf(err, _("cannot lock ref '%s': "
1056
"expected symref with target '%s': "
1057
"but is a regular ref"),
1058
ref_update_original_update_refname(u),
1064
if (ref_update_check_old_target(referent.buf, u, err)) {
1068
} else if ((u->flags & REF_HAVE_OLD) && !oideq(¤t_oid, &u->old_oid)) {
1069
if (is_null_oid(&u->old_oid))
1070
strbuf_addf(err, _("cannot lock ref '%s': "
1071
"reference already exists"),
1072
ref_update_original_update_refname(u));
1073
else if (is_null_oid(¤t_oid))
1074
strbuf_addf(err, _("cannot lock ref '%s': "
1075
"reference is missing but expected %s"),
1076
ref_update_original_update_refname(u),
1077
oid_to_hex(&u->old_oid));
1079
strbuf_addf(err, _("cannot lock ref '%s': "
1080
"is at %s but expected %s"),
1081
ref_update_original_update_refname(u),
1082
oid_to_hex(¤t_oid),
1083
oid_to_hex(&u->old_oid));
1099
if ((u->type & REF_ISSYMREF) ||
1100
(u->flags & REF_LOG_ONLY) ||
1101
(u->flags & REF_HAVE_NEW && !oideq(¤t_oid, &u->new_oid))) {
1102
ret = queue_transaction_update(refs, tx_data, u,
1109
transaction->backend_data = tx_data;
1110
transaction->state = REF_TRANSACTION_PREPARED;
1113
assert(ret != REFTABLE_API_ERROR);
1115
free_transaction_data(tx_data);
1116
transaction->state = REF_TRANSACTION_CLOSED;
1118
strbuf_addf(err, _("reftable: transaction prepare: %s"),
1119
reftable_error_str(ret));
1121
string_list_clear(&affected_refnames, 0);
1122
strbuf_release(&referent);
1123
strbuf_release(&head_referent);
1128
static int reftable_be_transaction_abort(struct ref_store *ref_store UNUSED,
1129
struct ref_transaction *transaction,
1130
struct strbuf *err UNUSED)
1132
struct reftable_transaction_data *tx_data = transaction->backend_data;
1133
free_transaction_data(tx_data);
1134
transaction->state = REF_TRANSACTION_CLOSED;
1138
static int transaction_update_cmp(const void *a, const void *b)
1140
return strcmp(((struct reftable_transaction_update *)a)->update->refname,
1141
((struct reftable_transaction_update *)b)->update->refname);
1144
static int write_transaction_table(struct reftable_writer *writer, void *cb_data)
1146
struct write_transaction_table_arg *arg = cb_data;
1147
uint64_t ts = reftable_stack_next_update_index(arg->stack);
1148
struct reftable_log_record *logs = NULL;
1149
struct ident_split committer_ident = {0};
1150
size_t logs_nr = 0, logs_alloc = 0, i;
1151
const char *committer_info;
1154
committer_info = git_committer_info(0);
1155
if (split_ident_line(&committer_ident, committer_info, strlen(committer_info)))
1156
BUG("failed splitting committer info");
1158
QSORT(arg->updates, arg->updates_nr, transaction_update_cmp);
1160
reftable_writer_set_limits(writer, ts, ts);
1162
for (i = 0; i < arg->updates_nr; i++) {
1163
struct reftable_transaction_update *tx_update = &arg->updates[i];
1164
struct ref_update *u = tx_update->update;
1177
if ((u->flags & REF_HAVE_NEW) &&
1178
!(u->type & REF_ISSYMREF) &&
1179
ref_update_has_null_new_value(u)) {
1180
struct reftable_log_record log = {0};
1181
struct reftable_iterator it = {0};
1183
reftable_stack_init_log_iterator(arg->stack, &it);
1194
ret = reftable_iterator_seek_log(&it, u->refname);
1196
struct reftable_log_record *tombstone;
1198
ret = reftable_iterator_next_log(&it, &log);
1201
if (ret > 0 || strcmp(log.refname, u->refname)) {
1206
ALLOC_GROW(logs, logs_nr + 1, logs_alloc);
1207
tombstone = &logs[logs_nr++];
1208
tombstone->refname = xstrdup(u->refname);
1209
tombstone->value_type = REFTABLE_LOG_DELETION;
1210
tombstone->update_index = log.update_index;
1213
reftable_log_record_release(&log);
1214
reftable_iterator_destroy(&it);
1218
} else if (!(u->flags & REF_SKIP_CREATE_REFLOG) &&
1219
(u->flags & REF_HAVE_NEW) &&
1220
(u->flags & REF_FORCE_CREATE_REFLOG ||
1221
should_write_log(&arg->refs->base, u->refname))) {
1222
struct reftable_log_record *log;
1223
int create_reflog = 1;
1225
if (u->new_target) {
1226
if (!refs_resolve_ref_unsafe(&arg->refs->base, u->new_target,
1227
RESOLVE_REF_READING, &u->new_oid, NULL)) {
1237
if (create_reflog) {
1238
ALLOC_GROW(logs, logs_nr + 1, logs_alloc);
1239
log = &logs[logs_nr++];
1240
memset(log, 0, sizeof(*log));
1242
fill_reftable_log_record(log, &committer_ident);
1243
log->update_index = ts;
1244
log->refname = xstrdup(u->refname);
1245
memcpy(log->value.update.new_hash,
1246
u->new_oid.hash, GIT_MAX_RAWSZ);
1247
memcpy(log->value.update.old_hash,
1248
tx_update->current_oid.hash, GIT_MAX_RAWSZ);
1249
log->value.update.message =
1250
xstrndup(u->msg, arg->refs->write_options.block_size / 2);
1254
if (u->flags & REF_LOG_ONLY)
1257
if (u->new_target) {
1258
struct reftable_ref_record ref = {
1259
.refname = (char *)u->refname,
1260
.value_type = REFTABLE_REF_SYMREF,
1261
.value.symref = (char *)u->new_target,
1265
ret = reftable_writer_add_ref(writer, &ref);
1268
} else if ((u->flags & REF_HAVE_NEW) && ref_update_has_null_new_value(u)) {
1269
struct reftable_ref_record ref = {
1270
.refname = (char *)u->refname,
1272
.value_type = REFTABLE_REF_DELETION,
1275
ret = reftable_writer_add_ref(writer, &ref);
1278
} else if (u->flags & REF_HAVE_NEW) {
1279
struct reftable_ref_record ref = {0};
1280
struct object_id peeled;
1283
ref.refname = (char *)u->refname;
1284
ref.update_index = ts;
1286
peel_error = peel_object(arg->refs->base.repo, &u->new_oid, &peeled);
1288
ref.value_type = REFTABLE_REF_VAL2;
1289
memcpy(ref.value.val2.target_value, peeled.hash, GIT_MAX_RAWSZ);
1290
memcpy(ref.value.val2.value, u->new_oid.hash, GIT_MAX_RAWSZ);
1291
} else if (!is_null_oid(&u->new_oid)) {
1292
ref.value_type = REFTABLE_REF_VAL1;
1293
memcpy(ref.value.val1, u->new_oid.hash, GIT_MAX_RAWSZ);
1296
ret = reftable_writer_add_ref(writer, &ref);
1307
ret = reftable_writer_add_logs(writer, logs, logs_nr);
1313
assert(ret != REFTABLE_API_ERROR);
1314
for (i = 0; i < logs_nr; i++)
1315
reftable_log_record_release(&logs[i]);
1320
static int reftable_be_transaction_finish(struct ref_store *ref_store UNUSED,
1321
struct ref_transaction *transaction,
1324
struct reftable_transaction_data *tx_data = transaction->backend_data;
1327
for (size_t i = 0; i < tx_data->args_nr; i++) {
1328
ret = reftable_addition_add(tx_data->args[i].addition,
1329
write_transaction_table, &tx_data->args[i]);
1333
ret = reftable_addition_commit(tx_data->args[i].addition);
1339
assert(ret != REFTABLE_API_ERROR);
1340
free_transaction_data(tx_data);
1341
transaction->state = REF_TRANSACTION_CLOSED;
1344
strbuf_addf(err, _("reftable: transaction failure: %s"),
1345
reftable_error_str(ret));
1351
static int reftable_be_initial_transaction_commit(struct ref_store *ref_store UNUSED,
1352
struct ref_transaction *transaction,
1355
return ref_transaction_commit(transaction, err);
1358
static int reftable_be_pack_refs(struct ref_store *ref_store,
1359
struct pack_refs_opts *opts)
1361
struct reftable_ref_store *refs =
1362
reftable_be_downcast(ref_store, REF_STORE_WRITE | REF_STORE_ODB, "pack_refs");
1363
struct reftable_stack *stack;
1369
stack = refs->worktree_stack;
1371
stack = refs->main_stack;
1373
if (opts->flags & PACK_REFS_AUTO)
1374
ret = reftable_stack_auto_compact(stack);
1376
ret = reftable_stack_compact_all(stack, NULL);
1378
ret = error(_("unable to compact stack: %s"),
1379
reftable_error_str(ret));
1383
ret = reftable_stack_clean(stack);
1391
struct write_create_symref_arg {
1392
struct reftable_ref_store *refs;
1393
struct reftable_stack *stack;
1395
const char *refname;
1400
struct write_copy_arg {
1401
struct reftable_ref_store *refs;
1402
struct reftable_stack *stack;
1403
const char *oldname;
1404
const char *newname;
1409
static int write_copy_table(struct reftable_writer *writer, void *cb_data)
1411
struct write_copy_arg *arg = cb_data;
1412
uint64_t deletion_ts, creation_ts;
1413
struct reftable_ref_record old_ref = {0}, refs[2] = {0};
1414
struct reftable_log_record old_log = {0}, *logs = NULL;
1415
struct reftable_iterator it = {0};
1416
struct string_list skip = STRING_LIST_INIT_NODUP;
1417
struct ident_split committer_ident = {0};
1418
struct strbuf errbuf = STRBUF_INIT;
1419
size_t logs_nr = 0, logs_alloc = 0, i;
1420
const char *committer_info;
1423
committer_info = git_committer_info(0);
1424
if (split_ident_line(&committer_ident, committer_info, strlen(committer_info)))
1425
BUG("failed splitting committer info");
1427
if (reftable_stack_read_ref(arg->stack, arg->oldname, &old_ref)) {
1428
ret = error(_("refname %s not found"), arg->oldname);
1431
if (old_ref.value_type == REFTABLE_REF_SYMREF) {
1432
ret = error(_("refname %s is a symbolic ref, copying it is not supported"),
1441
if (!strcmp(arg->oldname, arg->newname)) {
1449
if (arg->delete_old)
1450
string_list_insert(&skip, arg->oldname);
1451
ret = refs_verify_refname_available(&arg->refs->base, arg->newname,
1452
NULL, &skip, &errbuf);
1454
error("%s", errbuf.buf);
1466
deletion_ts = creation_ts = reftable_stack_next_update_index(arg->stack);
1467
if (arg->delete_old)
1469
reftable_writer_set_limits(writer, deletion_ts, creation_ts);
1476
refs[0].refname = xstrdup(arg->newname);
1477
refs[0].update_index = creation_ts;
1478
if (arg->delete_old) {
1479
refs[1].refname = xstrdup(arg->oldname);
1480
refs[1].value_type = REFTABLE_REF_DELETION;
1481
refs[1].update_index = deletion_ts;
1483
ret = reftable_writer_add_refs(writer, refs, arg->delete_old ? 2 : 1);
1493
if (arg->delete_old) {
1494
struct strbuf head_referent = STRBUF_INIT;
1495
struct object_id head_oid;
1496
int append_head_reflog;
1497
unsigned head_type = 0;
1499
ALLOC_GROW(logs, logs_nr + 1, logs_alloc);
1500
memset(&logs[logs_nr], 0, sizeof(logs[logs_nr]));
1501
fill_reftable_log_record(&logs[logs_nr], &committer_ident);
1502
logs[logs_nr].refname = xstrdup(arg->newname);
1503
logs[logs_nr].update_index = deletion_ts;
1504
logs[logs_nr].value.update.message =
1505
xstrndup(arg->logmsg, arg->refs->write_options.block_size / 2);
1506
memcpy(logs[logs_nr].value.update.old_hash, old_ref.value.val1, GIT_MAX_RAWSZ);
1509
ret = read_ref_without_reload(arg->refs, arg->stack, "HEAD", &head_oid,
1510
&head_referent, &head_type);
1513
append_head_reflog = (head_type & REF_ISSYMREF) && !strcmp(head_referent.buf, arg->oldname);
1514
strbuf_release(&head_referent);
1521
if (append_head_reflog) {
1522
ALLOC_GROW(logs, logs_nr + 1, logs_alloc);
1523
logs[logs_nr] = logs[logs_nr - 1];
1524
logs[logs_nr].refname = xstrdup("HEAD");
1525
logs[logs_nr].value.update.name =
1526
xstrdup(logs[logs_nr].value.update.name);
1527
logs[logs_nr].value.update.email =
1528
xstrdup(logs[logs_nr].value.update.email);
1529
logs[logs_nr].value.update.message =
1530
xstrdup(logs[logs_nr].value.update.message);
1538
ALLOC_GROW(logs, logs_nr + 1, logs_alloc);
1539
memset(&logs[logs_nr], 0, sizeof(logs[logs_nr]));
1540
fill_reftable_log_record(&logs[logs_nr], &committer_ident);
1541
logs[logs_nr].refname = xstrdup(arg->newname);
1542
logs[logs_nr].update_index = creation_ts;
1543
logs[logs_nr].value.update.message =
1544
xstrndup(arg->logmsg, arg->refs->write_options.block_size / 2);
1545
memcpy(logs[logs_nr].value.update.new_hash, old_ref.value.val1, GIT_MAX_RAWSZ);
1553
reftable_stack_init_log_iterator(arg->stack, &it);
1554
ret = reftable_iterator_seek_log(&it, arg->oldname);
1559
ret = reftable_iterator_next_log(&it, &old_log);
1562
if (ret > 0 || strcmp(old_log.refname, arg->oldname)) {
1567
free(old_log.refname);
1572
ALLOC_GROW(logs, logs_nr + 1, logs_alloc);
1573
logs[logs_nr] = old_log;
1574
logs[logs_nr].refname = xstrdup(arg->newname);
1580
if (arg->delete_old) {
1581
ALLOC_GROW(logs, logs_nr + 1, logs_alloc);
1582
memset(&logs[logs_nr], 0, sizeof(logs[logs_nr]));
1583
logs[logs_nr].refname = xstrdup(arg->oldname);
1584
logs[logs_nr].value_type = REFTABLE_LOG_DELETION;
1585
logs[logs_nr].update_index = old_log.update_index;
1594
memset(&old_log, 0, sizeof(old_log));
1597
ret = reftable_writer_add_logs(writer, logs, logs_nr);
1602
assert(ret != REFTABLE_API_ERROR);
1603
reftable_iterator_destroy(&it);
1604
string_list_clear(&skip, 0);
1605
strbuf_release(&errbuf);
1606
for (i = 0; i < logs_nr; i++)
1607
reftable_log_record_release(&logs[i]);
1609
for (i = 0; i < ARRAY_SIZE(refs); i++)
1610
reftable_ref_record_release(&refs[i]);
1611
reftable_ref_record_release(&old_ref);
1612
reftable_log_record_release(&old_log);
1616
static int reftable_be_rename_ref(struct ref_store *ref_store,
1617
const char *oldrefname,
1618
const char *newrefname,
1621
struct reftable_ref_store *refs =
1622
reftable_be_downcast(ref_store, REF_STORE_WRITE, "rename_ref");
1623
struct reftable_stack *stack = stack_for(refs, newrefname, &newrefname);
1624
struct write_copy_arg arg = {
1627
.oldname = oldrefname,
1628
.newname = newrefname,
1638
ret = reftable_stack_reload(stack);
1641
ret = reftable_stack_add(stack, &write_copy_table, &arg);
1644
assert(ret != REFTABLE_API_ERROR);
1648
static int reftable_be_copy_ref(struct ref_store *ref_store,
1649
const char *oldrefname,
1650
const char *newrefname,
1653
struct reftable_ref_store *refs =
1654
reftable_be_downcast(ref_store, REF_STORE_WRITE, "copy_ref");
1655
struct reftable_stack *stack = stack_for(refs, newrefname, &newrefname);
1656
struct write_copy_arg arg = {
1659
.oldname = oldrefname,
1660
.newname = newrefname,
1669
ret = reftable_stack_reload(stack);
1672
ret = reftable_stack_add(stack, &write_copy_table, &arg);
1675
assert(ret != REFTABLE_API_ERROR);
1679
struct reftable_reflog_iterator {
1680
struct ref_iterator base;
1681
struct reftable_ref_store *refs;
1682
struct reftable_iterator iter;
1683
struct reftable_log_record log;
1684
struct strbuf last_name;
1688
static int reftable_reflog_iterator_advance(struct ref_iterator *ref_iterator)
1690
struct reftable_reflog_iterator *iter =
1691
(struct reftable_reflog_iterator *)ref_iterator;
1693
while (!iter->err) {
1694
iter->err = reftable_iterator_next_log(&iter->iter, &iter->log);
1703
if (!strcmp(iter->log.refname, iter->last_name.buf))
1706
if (check_refname_format(iter->log.refname,
1707
REFNAME_ALLOW_ONELEVEL))
1710
strbuf_reset(&iter->last_name);
1711
strbuf_addstr(&iter->last_name, iter->log.refname);
1712
iter->base.refname = iter->log.refname;
1717
if (iter->err > 0) {
1718
if (ref_iterator_abort(ref_iterator) != ITER_DONE)
1723
if (iter->err < 0) {
1724
ref_iterator_abort(ref_iterator);
1731
static int reftable_reflog_iterator_peel(struct ref_iterator *ref_iterator UNUSED,
1732
struct object_id *peeled UNUSED)
1734
BUG("reftable reflog iterator cannot be peeled");
1738
static int reftable_reflog_iterator_abort(struct ref_iterator *ref_iterator)
1740
struct reftable_reflog_iterator *iter =
1741
(struct reftable_reflog_iterator *)ref_iterator;
1742
reftable_log_record_release(&iter->log);
1743
reftable_iterator_destroy(&iter->iter);
1744
strbuf_release(&iter->last_name);
1749
static struct ref_iterator_vtable reftable_reflog_iterator_vtable = {
1750
.advance = reftable_reflog_iterator_advance,
1751
.peel = reftable_reflog_iterator_peel,
1752
.abort = reftable_reflog_iterator_abort
1755
static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftable_ref_store *refs,
1756
struct reftable_stack *stack)
1758
struct reftable_reflog_iterator *iter;
1761
iter = xcalloc(1, sizeof(*iter));
1762
base_ref_iterator_init(&iter->base, &reftable_reflog_iterator_vtable);
1763
strbuf_init(&iter->last_name, 0);
1770
ret = reftable_stack_reload(stack);
1774
reftable_stack_init_log_iterator(stack, &iter->iter);
1775
ret = reftable_iterator_seek_log(&iter->iter, "");
1784
static struct ref_iterator *reftable_be_reflog_iterator_begin(struct ref_store *ref_store)
1786
struct reftable_ref_store *refs =
1787
reftable_be_downcast(ref_store, REF_STORE_READ, "reflog_iterator_begin");
1788
struct reftable_reflog_iterator *main_iter, *worktree_iter;
1790
main_iter = reflog_iterator_for_stack(refs, refs->main_stack);
1791
if (!refs->worktree_stack)
1792
return &main_iter->base;
1794
worktree_iter = reflog_iterator_for_stack(refs, refs->worktree_stack);
1796
return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base,
1797
ref_iterator_select, NULL);
1800
static int yield_log_record(struct reftable_ref_store *refs,
1801
struct reftable_log_record *log,
1802
each_reflog_ent_fn fn,
1805
struct object_id old_oid, new_oid;
1806
const char *full_committer;
1808
oidread(&old_oid, log->value.update.old_hash, refs->base.repo->hash_algo);
1809
oidread(&new_oid, log->value.update.new_hash, refs->base.repo->hash_algo);
1816
if (is_null_oid(&old_oid) && is_null_oid(&new_oid))
1819
full_committer = fmt_ident(log->value.update.name, log->value.update.email,
1820
WANT_COMMITTER_IDENT, NULL, IDENT_NO_DATE);
1821
return fn(&old_oid, &new_oid, full_committer,
1822
log->value.update.time, log->value.update.tz_offset,
1823
log->value.update.message, cb_data);
1826
static int reftable_be_for_each_reflog_ent_reverse(struct ref_store *ref_store,
1827
const char *refname,
1828
each_reflog_ent_fn fn,
1831
struct reftable_ref_store *refs =
1832
reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent_reverse");
1833
struct reftable_stack *stack = stack_for(refs, refname, &refname);
1834
struct reftable_log_record log = {0};
1835
struct reftable_iterator it = {0};
1841
reftable_stack_init_log_iterator(stack, &it);
1842
ret = reftable_iterator_seek_log(&it, refname);
1844
ret = reftable_iterator_next_log(&it, &log);
1847
if (ret > 0 || strcmp(log.refname, refname)) {
1852
ret = yield_log_record(refs, &log, fn, cb_data);
1857
reftable_log_record_release(&log);
1858
reftable_iterator_destroy(&it);
1862
static int reftable_be_for_each_reflog_ent(struct ref_store *ref_store,
1863
const char *refname,
1864
each_reflog_ent_fn fn,
1867
struct reftable_ref_store *refs =
1868
reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent");
1869
struct reftable_stack *stack = stack_for(refs, refname, &refname);
1870
struct reftable_log_record *logs = NULL;
1871
struct reftable_iterator it = {0};
1872
size_t logs_alloc = 0, logs_nr = 0, i;
1878
reftable_stack_init_log_iterator(stack, &it);
1879
ret = reftable_iterator_seek_log(&it, refname);
1881
struct reftable_log_record log = {0};
1883
ret = reftable_iterator_next_log(&it, &log);
1886
if (ret > 0 || strcmp(log.refname, refname)) {
1887
reftable_log_record_release(&log);
1892
ALLOC_GROW(logs, logs_nr + 1, logs_alloc);
1893
logs[logs_nr++] = log;
1896
for (i = logs_nr; i--;) {
1897
ret = yield_log_record(refs, &logs[i], fn, cb_data);
1903
reftable_iterator_destroy(&it);
1904
for (i = 0; i < logs_nr; i++)
1905
reftable_log_record_release(&logs[i]);
1910
static int reftable_be_reflog_exists(struct ref_store *ref_store,
1911
const char *refname)
1913
struct reftable_ref_store *refs =
1914
reftable_be_downcast(ref_store, REF_STORE_READ, "reflog_exists");
1915
struct reftable_stack *stack = stack_for(refs, refname, &refname);
1916
struct reftable_log_record log = {0};
1917
struct reftable_iterator it = {0};
1924
ret = reftable_stack_reload(stack);
1928
reftable_stack_init_log_iterator(stack, &it);
1929
ret = reftable_iterator_seek_log(&it, refname);
1937
ret = reftable_iterator_next_log(&it, &log);
1945
ret = strcmp(log.refname, refname) == 0;
1948
reftable_iterator_destroy(&it);
1949
reftable_log_record_release(&log);
1955
struct write_reflog_existence_arg {
1956
struct reftable_ref_store *refs;
1957
const char *refname;
1958
struct reftable_stack *stack;
1961
static int write_reflog_existence_table(struct reftable_writer *writer,
1964
struct write_reflog_existence_arg *arg = cb_data;
1965
uint64_t ts = reftable_stack_next_update_index(arg->stack);
1966
struct reftable_log_record log = {0};
1969
ret = reftable_stack_read_log(arg->stack, arg->refname, &log);
1973
reftable_writer_set_limits(writer, ts, ts);
1980
log.refname = xstrdup(arg->refname);
1981
log.update_index = ts;
1982
log.value_type = REFTABLE_LOG_UPDATE;
1983
ret = reftable_writer_add_log(writer, &log);
1986
assert(ret != REFTABLE_API_ERROR);
1987
reftable_log_record_release(&log);
1991
static int reftable_be_create_reflog(struct ref_store *ref_store,
1992
const char *refname,
1993
struct strbuf *errmsg UNUSED)
1995
struct reftable_ref_store *refs =
1996
reftable_be_downcast(ref_store, REF_STORE_WRITE, "create_reflog");
1997
struct reftable_stack *stack = stack_for(refs, refname, &refname);
1998
struct write_reflog_existence_arg arg = {
2009
ret = reftable_stack_reload(stack);
2013
ret = reftable_stack_add(stack, &write_reflog_existence_table, &arg);
2019
struct write_reflog_delete_arg {
2020
struct reftable_stack *stack;
2021
const char *refname;
2024
static int write_reflog_delete_table(struct reftable_writer *writer, void *cb_data)
2026
struct write_reflog_delete_arg *arg = cb_data;
2027
struct reftable_log_record log = {0}, tombstone = {0};
2028
struct reftable_iterator it = {0};
2029
uint64_t ts = reftable_stack_next_update_index(arg->stack);
2032
reftable_writer_set_limits(writer, ts, ts);
2034
reftable_stack_init_log_iterator(arg->stack, &it);
2041
ret = reftable_iterator_seek_log(&it, arg->refname);
2043
ret = reftable_iterator_next_log(&it, &log);
2046
if (ret > 0 || strcmp(log.refname, arg->refname)) {
2051
tombstone.refname = (char *)arg->refname;
2052
tombstone.value_type = REFTABLE_LOG_DELETION;
2053
tombstone.update_index = log.update_index;
2055
ret = reftable_writer_add_log(writer, &tombstone);
2058
reftable_log_record_release(&log);
2059
reftable_iterator_destroy(&it);
2063
static int reftable_be_delete_reflog(struct ref_store *ref_store,
2064
const char *refname)
2066
struct reftable_ref_store *refs =
2067
reftable_be_downcast(ref_store, REF_STORE_WRITE, "delete_reflog");
2068
struct reftable_stack *stack = stack_for(refs, refname, &refname);
2069
struct write_reflog_delete_arg arg = {
2075
ret = reftable_stack_reload(stack);
2078
ret = reftable_stack_add(stack, &write_reflog_delete_table, &arg);
2080
assert(ret != REFTABLE_API_ERROR);
2084
struct reflog_expiry_arg {
2085
struct reftable_ref_store *refs;
2086
struct reftable_stack *stack;
2087
struct reftable_log_record *records;
2088
struct object_id update_oid;
2089
const char *refname;
2093
static int write_reflog_expiry_table(struct reftable_writer *writer, void *cb_data)
2095
struct reflog_expiry_arg *arg = cb_data;
2096
uint64_t ts = reftable_stack_next_update_index(arg->stack);
2097
uint64_t live_records = 0;
2101
for (i = 0; i < arg->len; i++)
2102
if (arg->records[i].value_type == REFTABLE_LOG_UPDATE)
2105
reftable_writer_set_limits(writer, ts, ts);
2107
if (!is_null_oid(&arg->update_oid)) {
2108
struct reftable_ref_record ref = {0};
2109
struct object_id peeled;
2111
ref.refname = (char *)arg->refname;
2112
ref.update_index = ts;
2114
if (!peel_object(arg->refs->base.repo, &arg->update_oid, &peeled)) {
2115
ref.value_type = REFTABLE_REF_VAL2;
2116
memcpy(ref.value.val2.target_value, peeled.hash, GIT_MAX_RAWSZ);
2117
memcpy(ref.value.val2.value, arg->update_oid.hash, GIT_MAX_RAWSZ);
2119
ref.value_type = REFTABLE_REF_VAL1;
2120
memcpy(ref.value.val1, arg->update_oid.hash, GIT_MAX_RAWSZ);
2123
ret = reftable_writer_add_ref(writer, &ref);
2133
if (!live_records) {
2134
struct reftable_log_record log = {
2135
.refname = (char *)arg->refname,
2136
.value_type = REFTABLE_LOG_UPDATE,
2140
ret = reftable_writer_add_log(writer, &log);
2145
for (i = 0; i < arg->len; i++) {
2146
ret = reftable_writer_add_log(writer, &arg->records[i]);
2154
static int reftable_be_reflog_expire(struct ref_store *ref_store,
2155
const char *refname,
2157
reflog_expiry_prepare_fn prepare_fn,
2158
reflog_expiry_should_prune_fn should_prune_fn,
2159
reflog_expiry_cleanup_fn cleanup_fn,
2160
void *policy_cb_data)
2175
struct reftable_ref_store *refs =
2176
reftable_be_downcast(ref_store, REF_STORE_WRITE, "reflog_expire");
2177
struct reftable_stack *stack = stack_for(refs, refname, &refname);
2178
struct reftable_log_record *logs = NULL;
2179
struct reftable_log_record *rewritten = NULL;
2180
struct reftable_ref_record ref_record = {0};
2181
struct reftable_iterator it = {0};
2182
struct reftable_addition *add = NULL;
2183
struct reflog_expiry_arg arg = {0};
2184
struct object_id oid = {0};
2185
uint8_t *last_hash = NULL;
2186
size_t logs_nr = 0, logs_alloc = 0, i;
2192
ret = reftable_stack_reload(stack);
2196
reftable_stack_init_log_iterator(stack, &it);
2198
ret = reftable_iterator_seek_log(&it, refname);
2202
ret = reftable_stack_new_addition(&add, stack);
2206
ret = reftable_stack_read_ref(stack, refname, &ref_record);
2209
if (reftable_ref_record_val1(&ref_record))
2210
oidread(&oid, reftable_ref_record_val1(&ref_record),
2211
ref_store->repo->hash_algo);
2212
prepare_fn(refname, &oid, policy_cb_data);
2215
struct reftable_log_record log = {0};
2216
struct object_id old_oid, new_oid;
2218
ret = reftable_iterator_next_log(&it, &log);
2221
if (ret > 0 || strcmp(log.refname, refname)) {
2222
reftable_log_record_release(&log);
2226
oidread(&old_oid, log.value.update.old_hash,
2227
ref_store->repo->hash_algo);
2228
oidread(&new_oid, log.value.update.new_hash,
2229
ref_store->repo->hash_algo);
2235
if (is_null_oid(&old_oid) && is_null_oid(&new_oid)) {
2236
reftable_log_record_release(&log);
2240
ALLOC_GROW(logs, logs_nr + 1, logs_alloc);
2241
logs[logs_nr++] = log;
2254
CALLOC_ARRAY(rewritten, logs_nr);
2255
for (i = logs_nr; i--;) {
2256
struct reftable_log_record *dest = &rewritten[i];
2257
struct object_id old_oid, new_oid;
2260
oidread(&old_oid, logs[i].value.update.old_hash,
2261
ref_store->repo->hash_algo);
2262
oidread(&new_oid, logs[i].value.update.new_hash,
2263
ref_store->repo->hash_algo);
2265
if (should_prune_fn(&old_oid, &new_oid, logs[i].value.update.email,
2266
(timestamp_t)logs[i].value.update.time,
2267
logs[i].value.update.tz_offset,
2268
logs[i].value.update.message,
2270
dest->value_type = REFTABLE_LOG_DELETION;
2272
if ((flags & EXPIRE_REFLOGS_REWRITE) && last_hash)
2273
memcpy(dest->value.update.old_hash, last_hash, GIT_MAX_RAWSZ);
2274
last_hash = logs[i].value.update.new_hash;
2278
if (flags & EXPIRE_REFLOGS_UPDATE_REF && last_hash &&
2279
reftable_ref_record_val1(&ref_record))
2280
oidread(&arg.update_oid, last_hash, ref_store->repo->hash_algo);
2283
arg.records = rewritten;
2286
arg.refname = refname,
2288
ret = reftable_addition_add(add, &write_reflog_expiry_table, &arg);
2296
if (!(flags & EXPIRE_REFLOGS_DRY_RUN))
2297
ret = reftable_addition_commit(add);
2301
cleanup_fn(policy_cb_data);
2302
assert(ret != REFTABLE_API_ERROR);
2304
reftable_ref_record_release(&ref_record);
2305
reftable_iterator_destroy(&it);
2306
reftable_addition_destroy(add);
2307
for (i = 0; i < logs_nr; i++)
2308
reftable_log_record_release(&logs[i]);
2314
static int reftable_be_fsck(struct ref_store *ref_store UNUSED,
2315
struct fsck_options *o UNUSED)
2320
struct ref_storage_be refs_be_reftable = {
2322
.init = reftable_be_init,
2323
.release = reftable_be_release,
2324
.create_on_disk = reftable_be_create_on_disk,
2325
.remove_on_disk = reftable_be_remove_on_disk,
2327
.transaction_prepare = reftable_be_transaction_prepare,
2328
.transaction_finish = reftable_be_transaction_finish,
2329
.transaction_abort = reftable_be_transaction_abort,
2330
.initial_transaction_commit = reftable_be_initial_transaction_commit,
2332
.pack_refs = reftable_be_pack_refs,
2333
.rename_ref = reftable_be_rename_ref,
2334
.copy_ref = reftable_be_copy_ref,
2336
.iterator_begin = reftable_be_iterator_begin,
2337
.read_raw_ref = reftable_be_read_raw_ref,
2338
.read_symbolic_ref = reftable_be_read_symbolic_ref,
2340
.reflog_iterator_begin = reftable_be_reflog_iterator_begin,
2341
.for_each_reflog_ent = reftable_be_for_each_reflog_ent,
2342
.for_each_reflog_ent_reverse = reftable_be_for_each_reflog_ent_reverse,
2343
.reflog_exists = reftable_be_reflog_exists,
2344
.create_reflog = reftable_be_create_reflog,
2345
.delete_reflog = reftable_be_delete_reflog,
2346
.reflog_expire = reftable_be_reflog_expire,
2348
.fsck = reftable_be_fsck,