mirror of
https://github.com/git/git.git
synced 2026-01-11 21:33:13 +09:00
refs/reftable: introduce generic checks for refs
In a preceding commit we have extracted generic checks for both direct and symbolic refs that apply for all backends. Wire up those checks for the "reftable" backend. Note that this is done by iterating through all refs manually with the low-level reftable ref iterator. We explicitly don't want to use the higher-level iterator that is exposed to users of the reftable backend as that iterator may swallow for example broken refs. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
d385bc1b75
commit
8a3de73c64
@ -2767,19 +2767,89 @@ static int reftable_be_fsck(struct ref_store *ref_store, struct fsck_options *o,
|
||||
{
|
||||
struct reftable_ref_store *refs =
|
||||
reftable_be_downcast(ref_store, REF_STORE_READ, "fsck");
|
||||
struct reftable_ref_iterator *iter = NULL;
|
||||
struct reftable_ref_record ref = { 0 };
|
||||
struct fsck_ref_report report = { 0 };
|
||||
struct strbuf refname = STRBUF_INIT;
|
||||
struct reftable_backend *backend;
|
||||
int ret, errors = 0;
|
||||
|
||||
if (is_main_worktree(wt)) {
|
||||
backend = &refs->main_backend;
|
||||
} else {
|
||||
int ret = backend_for_worktree(&backend, refs, wt->id);
|
||||
if (ret < 0)
|
||||
return error(_("reftable stack for worktree '%s' is broken"),
|
||||
wt->id);
|
||||
ret = backend_for_worktree(&backend, refs, wt->id);
|
||||
if (ret < 0) {
|
||||
ret = error(_("reftable stack for worktree '%s' is broken"),
|
||||
wt->id);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
return reftable_fsck_check(backend->stack, reftable_fsck_error_handler,
|
||||
reftable_fsck_verbose_handler, o);
|
||||
errors |= reftable_fsck_check(backend->stack, reftable_fsck_error_handler,
|
||||
reftable_fsck_verbose_handler, o);
|
||||
|
||||
iter = ref_iterator_for_stack(refs, backend->stack, "", NULL, 0);
|
||||
if (!iter) {
|
||||
ret = error(_("could not create iterator for worktree '%s'"), wt->id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
ret = reftable_iterator_next_ref(&iter->iter, &ref);
|
||||
if (ret > 0)
|
||||
break;
|
||||
if (ret < 0) {
|
||||
ret = error(_("could not read record for worktree '%s'"), wt->id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
strbuf_reset(&refname);
|
||||
if (!is_main_worktree(wt))
|
||||
strbuf_addf(&refname, "worktrees/%s/", wt->id);
|
||||
strbuf_addstr(&refname, ref.refname);
|
||||
report.path = refname.buf;
|
||||
|
||||
switch (ref.value_type) {
|
||||
case REFTABLE_REF_VAL1:
|
||||
case REFTABLE_REF_VAL2: {
|
||||
struct object_id oid;
|
||||
unsigned hash_id;
|
||||
|
||||
switch (reftable_stack_hash_id(backend->stack)) {
|
||||
case REFTABLE_HASH_SHA1:
|
||||
hash_id = GIT_HASH_SHA1;
|
||||
break;
|
||||
case REFTABLE_HASH_SHA256:
|
||||
hash_id = GIT_HASH_SHA256;
|
||||
break;
|
||||
default:
|
||||
BUG("unhandled hash ID %d",
|
||||
reftable_stack_hash_id(backend->stack));
|
||||
}
|
||||
|
||||
oidread(&oid, reftable_ref_record_val1(&ref),
|
||||
&hash_algos[hash_id]);
|
||||
|
||||
errors |= refs_fsck_ref(ref_store, o, &report, ref.refname, &oid);
|
||||
break;
|
||||
}
|
||||
case REFTABLE_REF_SYMREF:
|
||||
errors |= refs_fsck_symref(ref_store, o, &report, ref.refname,
|
||||
ref.value.symref);
|
||||
break;
|
||||
default:
|
||||
BUG("unhandled reference value type %d", ref.value_type);
|
||||
}
|
||||
}
|
||||
|
||||
ret = errors ? -1 : 0;
|
||||
|
||||
out:
|
||||
if (iter)
|
||||
ref_iterator_free(&iter->base);
|
||||
reftable_ref_record_release(&ref);
|
||||
strbuf_release(&refname);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct ref_storage_be refs_be_reftable = {
|
||||
|
||||
@ -87,4 +87,16 @@ test_expect_success 'worktree stacks can be verified' '
|
||||
done
|
||||
'
|
||||
|
||||
test_expect_success 'invalid symref gets reported' '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init repo &&
|
||||
test_commit -C repo initial &&
|
||||
git -C repo symbolic-ref refs/heads/symref garbage &&
|
||||
test_must_fail git -C repo refs verify 2>err &&
|
||||
cat >expect <<-EOF &&
|
||||
error: refs/heads/symref: badReferentName: points to invalid refname ${SQ}garbage${SQ}
|
||||
EOF
|
||||
test_cmp expect err
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user