Skip to content

Commit 466a3a1

Browse files
KarthikNayakgitster
authored andcommitted
refs/reftable: add fsck check for checking the table name
Add glue code in 'refs/reftable-backend.c' which calls the reftable library to perform the fsck checks. Here we also map the reftable errors to Git' fsck errors. Introduce a check to validate table names for a given reftable stack. Also add 'badReftableTableName' as a corresponding error within Git. The reftable specification mentions: It suggested to use ${min_update_index}-${max_update_index}-${random}.ref as a naming convention. So treat non-conformant file names as warnings. While adding the fsck header to 'refs/reftable-backend.c', modify the list to maintain lexicographical ordering. Signed-off-by: Karthik Nayak <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9051638 commit 466a3a1

File tree

5 files changed

+115
-5
lines changed

5 files changed

+115
-5
lines changed

Documentation/fsck-msgids.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
`badReferentName`::
3939
(ERROR) The referent name of a symref is invalid.
4040

41+
`badReftableTableName`::
42+
(WARN) A reftable table has an invalid name.
43+
4144
`badTagName`::
4245
(INFO) A tag has an invalid format.
4346

fsck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ enum fsck_msg_type {
7373
FUNC(UNKNOWN_TYPE, ERROR) \
7474
FUNC(ZERO_PADDED_DATE, ERROR) \
7575
/* warnings */ \
76+
FUNC(BAD_REFTABLE_TABLE_NAME, WARN) \
7677
FUNC(EMPTY_NAME, WARN) \
7778
FUNC(FULL_PATHNAME, WARN) \
7879
FUNC(HAS_DOT, WARN) \

refs/reftable-backend.c

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "../config.h"
77
#include "../dir.h"
88
#include "../environment.h"
9+
#include "../fsck.h"
910
#include "../gettext.h"
1011
#include "../hash.h"
1112
#include "../hex.h"
@@ -15,10 +16,11 @@
1516
#include "../path.h"
1617
#include "../refs.h"
1718
#include "../reftable/reftable-basics.h"
18-
#include "../reftable/reftable-stack.h"
19-
#include "../reftable/reftable-record.h"
2019
#include "../reftable/reftable-error.h"
20+
#include "../reftable/reftable-fsck.h"
2121
#include "../reftable/reftable-iterator.h"
22+
#include "../reftable/reftable-record.h"
23+
#include "../reftable/reftable-stack.h"
2224
#include "../repo-settings.h"
2325
#include "../setup.h"
2426
#include "../strmap.h"
@@ -2674,11 +2676,56 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
26742676
return ret;
26752677
}
26762678

2677-
static int reftable_be_fsck(struct ref_store *ref_store UNUSED,
2678-
struct fsck_options *o UNUSED,
2679+
static void reftable_fsck_verbose_handler(const char *msg, void *cb_data)
2680+
{
2681+
struct fsck_options *o = cb_data;
2682+
2683+
if (o->verbose)
2684+
fprintf_ln(stderr, "%s", msg);
2685+
}
2686+
2687+
static const enum fsck_msg_id fsck_msg_id_map[] = {
2688+
[REFTABLE_FSCK_ERROR_TABLE_NAME] = FSCK_MSG_BAD_REFTABLE_TABLE_NAME,
2689+
};
2690+
2691+
static int reftable_fsck_error_handler(struct reftable_fsck_info *info,
2692+
void *cb_data)
2693+
{
2694+
struct fsck_ref_report report = { .path = info->path };
2695+
struct fsck_options *o = cb_data;
2696+
enum fsck_msg_id msg_id;
2697+
2698+
if (info->error < 0 || info->error >= REFTABLE_FSCK_MAX_VALUE)
2699+
BUG("unknown fsck error: %d", (int)info->error);
2700+
2701+
msg_id = fsck_msg_id_map[info->error];
2702+
2703+
if (!msg_id)
2704+
BUG("fsck_msg_id value missing for reftable error: %d", (int)info->error);
2705+
2706+
return fsck_report_ref(o, &report, msg_id, "%s", info->msg);
2707+
}
2708+
2709+
static int reftable_be_fsck(struct ref_store *ref_store, struct fsck_options *o,
26792710
struct worktree *wt UNUSED)
26802711
{
2681-
return 0;
2712+
struct reftable_ref_store *refs;
2713+
struct strmap_entry *entry;
2714+
struct hashmap_iter iter;
2715+
int ret = 0;
2716+
2717+
refs = reftable_be_downcast(ref_store, REF_STORE_READ, "fsck");
2718+
2719+
ret |= reftable_fsck_check(refs->main_backend.stack, reftable_fsck_error_handler,
2720+
reftable_fsck_verbose_handler, o);
2721+
2722+
strmap_for_each_entry(&refs->worktree_backends, &iter, entry) {
2723+
struct reftable_backend *b = (struct reftable_backend *)entry->value;
2724+
ret |= reftable_fsck_check(b->stack, reftable_fsck_error_handler,
2725+
reftable_fsck_verbose_handler, o);
2726+
}
2727+
2728+
return ret;
26822729
}
26832730

26842731
struct ref_storage_be refs_be_reftable = {

t/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ integration_tests = [
145145
't0611-reftable-httpd.sh',
146146
't0612-reftable-jgit-compatibility.sh',
147147
't0613-reftable-write-options.sh',
148+
't0614-reftable-fsck.sh',
148149
't1000-read-tree-m-3way.sh',
149150
't1001-read-tree-m-2way.sh',
150151
't1002-read-tree-m-u-2way.sh',

t/t0614-reftable-fsck.sh

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/bin/sh
2+
3+
test_description='Test reftable backend consistency check'
4+
5+
GIT_TEST_DEFAULT_REF_FORMAT=reftable
6+
export GIT_TEST_DEFAULT_REF_FORMAT
7+
8+
. ./test-lib.sh
9+
10+
test_expect_success "no errors reported on a well formed repository" '
11+
test_when_finished "rm -rf repo" &&
12+
git init repo &&
13+
(
14+
cd repo &&
15+
git commit --allow-empty -m initial &&
16+
17+
for i in $(test_seq 20)
18+
do
19+
git update-ref refs/heads/branch-$i HEAD || return 1
20+
done &&
21+
22+
# The repository should end up with multiple tables.
23+
test_line_count ">" 1 .git/reftable/tables.list &&
24+
25+
git refs verify 2>err &&
26+
test_must_be_empty err
27+
)
28+
'
29+
30+
for TABLE_NAME in "foo-bar-e4d12d59.ref" \
31+
"0x00000000zzzz-0x00000000zzzz-e4d12d59.ref" \
32+
"0x000000000001-0x000000000002-e4d12d59.abc" \
33+
"0x000000000001-0x000000000002-e4d12d59.refabc"; do
34+
test_expect_success "table name $TABLE_NAME should be checked" '
35+
test_when_finished "rm -rf repo" &&
36+
git init repo &&
37+
(
38+
cd repo &&
39+
git commit --allow-empty -m initial &&
40+
41+
git refs verify 2>err &&
42+
test_must_be_empty err &&
43+
44+
EXISTING_TABLE=$(head -n1 .git/reftable/tables.list) &&
45+
mv ".git/reftable/$EXISTING_TABLE" ".git/reftable/$TABLE_NAME" &&
46+
sed "s/${EXISTING_TABLE}/${TABLE_NAME}/g" .git/reftable/tables.list > tables.list &&
47+
mv tables.list .git/reftable/tables.list &&
48+
49+
git refs verify 2>err &&
50+
cat >expect <<-EOF &&
51+
warning: ${TABLE_NAME}: badReftableTableName: invalid reftable table name
52+
EOF
53+
test_cmp expect err
54+
)
55+
'
56+
done
57+
58+
test_done

0 commit comments

Comments
 (0)