Skip to content

Commit a7600b8

Browse files
shejialuogitster
authored andcommitted
files-backend: add unified interface for refs scanning
For refs and reflogs, we need to scan its corresponding directories to check every regular file or symbolic link which shares the same pattern. Introduce a unified interface for scanning directories for files-backend. Mentored-by: Patrick Steinhardt <[email protected]> Mentored-by: Karthik Nayak <[email protected]> Signed-off-by: shejialuo <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent bf061d2 commit a7600b8

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

Documentation/fsck-msgids.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
`badParentSha1`::
2020
(ERROR) A commit object has a bad parent sha1.
2121

22+
`badRefFiletype`::
23+
(ERROR) A ref has a bad file type.
24+
2225
`badTagName`::
2326
(INFO) A tag has an invalid format.
2427

fsck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ enum fsck_msg_type {
3131
FUNC(BAD_NAME, ERROR) \
3232
FUNC(BAD_OBJECT_SHA1, ERROR) \
3333
FUNC(BAD_PARENT_SHA1, ERROR) \
34+
FUNC(BAD_REF_FILETYPE, ERROR) \
3435
FUNC(BAD_TIMEZONE, ERROR) \
3536
FUNC(BAD_TREE, ERROR) \
3637
FUNC(BAD_TREE_SHA1, ERROR) \

refs/files-backend.c

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "../gettext.h"
77
#include "../hash.h"
88
#include "../hex.h"
9+
#include "../fsck.h"
910
#include "../refs.h"
1011
#include "refs-internal.h"
1112
#include "ref-cache.h"
@@ -3408,13 +3409,83 @@ static int files_ref_store_remove_on_disk(struct ref_store *ref_store,
34083409
return ret;
34093410
}
34103411

3412+
/*
3413+
* For refs and reflogs, they share a unified interface when scanning
3414+
* the whole directory. This function is used as the callback for each
3415+
* regular file or symlink in the directory.
3416+
*/
3417+
typedef int (*files_fsck_refs_fn)(struct ref_store *ref_store,
3418+
struct fsck_options *o,
3419+
const char *refs_check_dir,
3420+
struct dir_iterator *iter);
3421+
3422+
static int files_fsck_refs_dir(struct ref_store *ref_store,
3423+
struct fsck_options *o,
3424+
const char *refs_check_dir,
3425+
files_fsck_refs_fn *fsck_refs_fn)
3426+
{
3427+
struct strbuf sb = STRBUF_INIT;
3428+
struct dir_iterator *iter;
3429+
int iter_status;
3430+
int ret = 0;
3431+
3432+
strbuf_addf(&sb, "%s/%s", ref_store->gitdir, refs_check_dir);
3433+
3434+
iter = dir_iterator_begin(sb.buf, 0);
3435+
if (!iter) {
3436+
ret = error_errno(_("cannot open directory %s"), sb.buf);
3437+
goto out;
3438+
}
3439+
3440+
while ((iter_status = dir_iterator_advance(iter)) == ITER_OK) {
3441+
if (S_ISDIR(iter->st.st_mode)) {
3442+
continue;
3443+
} else if (S_ISREG(iter->st.st_mode) ||
3444+
S_ISLNK(iter->st.st_mode)) {
3445+
if (o->verbose)
3446+
fprintf_ln(stderr, "Checking %s/%s",
3447+
refs_check_dir, iter->relative_path);
3448+
for (size_t i = 0; fsck_refs_fn[i]; i++) {
3449+
if (fsck_refs_fn[i](ref_store, o, refs_check_dir, iter))
3450+
ret = -1;
3451+
}
3452+
} else {
3453+
struct fsck_ref_report report = { .path = iter->basename };
3454+
if (fsck_report_ref(o, &report,
3455+
FSCK_MSG_BAD_REF_FILETYPE,
3456+
"unexpected file type"))
3457+
ret = -1;
3458+
}
3459+
}
3460+
3461+
if (iter_status != ITER_DONE)
3462+
ret = error(_("failed to iterate over '%s'"), sb.buf);
3463+
3464+
out:
3465+
strbuf_release(&sb);
3466+
return ret;
3467+
}
3468+
3469+
static int files_fsck_refs(struct ref_store *ref_store,
3470+
struct fsck_options *o)
3471+
{
3472+
files_fsck_refs_fn fsck_refs_fn[]= {
3473+
NULL,
3474+
};
3475+
3476+
if (o->verbose)
3477+
fprintf_ln(stderr, _("Checking references consistency"));
3478+
return files_fsck_refs_dir(ref_store, o, "refs", fsck_refs_fn);
3479+
}
3480+
34113481
static int files_fsck(struct ref_store *ref_store,
34123482
struct fsck_options *o)
34133483
{
34143484
struct files_ref_store *refs =
34153485
files_downcast(ref_store, REF_STORE_READ, "fsck");
34163486

3417-
return refs->packed_ref_store->be->fsck(refs->packed_ref_store, o);
3487+
return files_fsck_refs(ref_store, o) |
3488+
refs->packed_ref_store->be->fsck(refs->packed_ref_store, o);
34183489
}
34193490

34203491
struct ref_storage_be refs_be_files = {

0 commit comments

Comments
 (0)