Skip to content

Commit de35b7b

Browse files
committed
Merge branch 'sj/ref-consistency-checks-more'
"git fsck" becomes more careful when checking the refs. * sj/ref-consistency-checks-more: builtin/fsck: add `git refs verify` child process packed-backend: check whether the "packed-refs" is sorted packed-backend: add "packed-refs" entry consistency check packed-backend: check whether the refname contains NUL characters packed-backend: add "packed-refs" header consistency check packed-backend: check if header starts with "# pack-refs with: " packed-backend: check whether the "packed-refs" is regular file builtin/refs: get worktrees without reading head information t0602: use subshell to ensure working directory unchanged
2 parents f50df87 + c1cf918 commit de35b7b

File tree

9 files changed

+1162
-483
lines changed

9 files changed

+1162
-483
lines changed

Documentation/fsck-msgids.adoc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
`badObjectSha1`::
1717
(ERROR) An object has a bad sha1.
1818

19+
`badPackedRefEntry`::
20+
(ERROR) The "packed-refs" file contains an invalid entry.
21+
22+
`badPackedRefHeader`::
23+
(ERROR) The "packed-refs" file contains an invalid
24+
header.
25+
1926
`badParentSha1`::
2027
(ERROR) A commit object has a bad parent sha1.
2128

@@ -176,6 +183,13 @@
176183
`nullSha1`::
177184
(WARN) Tree contains entries pointing to a null sha1.
178185

186+
`packedRefEntryNotTerminated`::
187+
(ERROR) The "packed-refs" file contains an entry that is
188+
not terminated by a newline.
189+
190+
`packedRefUnsorted`::
191+
(ERROR) The "packed-refs" file is not sorted.
192+
179193
`refMissingNewline`::
180194
(INFO) A loose ref that does not end with newline(LF). As
181195
valid implementations of Git never created such a loose ref

Documentation/git-fsck.adoc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ SYNOPSIS
1212
'git fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]
1313
[--[no-]full] [--strict] [--verbose] [--lost-found]
1414
[--[no-]dangling] [--[no-]progress] [--connectivity-only]
15-
[--[no-]name-objects] [<object>...]
15+
[--[no-]name-objects] [--[no-]references] [<object>...]
1616

1717
DESCRIPTION
1818
-----------
@@ -104,6 +104,11 @@ care about this output and want to speed it up further.
104104
progress status even if the standard error stream is not
105105
directed to a terminal.
106106

107+
--[no-]references::
108+
Control whether to check the references database consistency
109+
via 'git refs verify'. See linkgit:git-refs[1] for details.
110+
The default is to check the references database.
111+
107112
CONFIGURATION
108113
-------------
109114

builtin/fsck.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ static int verbose;
5050
static int show_progress = -1;
5151
static int show_dangling = 1;
5252
static int name_objects;
53+
static int check_references = 1;
5354
#define ERROR_OBJECT 01
5455
#define ERROR_REACHABLE 02
5556
#define ERROR_PACK 04
@@ -905,11 +906,37 @@ static int check_pack_rev_indexes(struct repository *r, int show_progress)
905906
return res;
906907
}
907908

909+
static void fsck_refs(struct repository *r)
910+
{
911+
struct child_process refs_verify = CHILD_PROCESS_INIT;
912+
struct progress *progress = NULL;
913+
914+
if (show_progress)
915+
progress = start_progress(r, _("Checking ref database"), 1);
916+
917+
if (verbose)
918+
fprintf_ln(stderr, _("Checking ref database"));
919+
920+
child_process_init(&refs_verify);
921+
refs_verify.git_cmd = 1;
922+
strvec_pushl(&refs_verify.args, "refs", "verify", NULL);
923+
if (verbose)
924+
strvec_push(&refs_verify.args, "--verbose");
925+
if (check_strict)
926+
strvec_push(&refs_verify.args, "--strict");
927+
928+
if (run_command(&refs_verify))
929+
errors_found |= ERROR_REFS;
930+
931+
display_progress(progress, 1);
932+
stop_progress(&progress);
933+
}
934+
908935
static char const * const fsck_usage[] = {
909936
N_("git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n"
910937
" [--[no-]full] [--strict] [--verbose] [--lost-found]\n"
911938
" [--[no-]dangling] [--[no-]progress] [--connectivity-only]\n"
912-
" [--[no-]name-objects] [<object>...]"),
939+
" [--[no-]name-objects] [--[no-]references] [<object>...]"),
913940
NULL
914941
};
915942

@@ -928,6 +955,7 @@ static struct option fsck_opts[] = {
928955
N_("write dangling objects in .git/lost-found")),
929956
OPT_BOOL(0, "progress", &show_progress, N_("show progress")),
930957
OPT_BOOL(0, "name-objects", &name_objects, N_("show verbose names for reachable objects")),
958+
OPT_BOOL(0, "references", &check_references, N_("check reference database consistency")),
931959
OPT_END(),
932960
};
933961

@@ -970,6 +998,9 @@ int cmd_fsck(int argc,
970998
git_config(git_fsck_config, &fsck_obj_options);
971999
prepare_repo_settings(the_repository);
9721000

1001+
if (check_references)
1002+
fsck_refs(the_repository);
1003+
9731004
if (connectivity_only) {
9741005
for_each_loose_object(mark_loose_for_connectivity, NULL, 0);
9751006
for_each_packed_object(the_repository,

builtin/refs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix,
9191
git_config(git_fsck_config, &fsck_refs_options);
9292
prepare_repo_settings(the_repository);
9393

94-
worktrees = get_worktrees();
94+
worktrees = get_worktrees_without_reading_head();
9595
for (size_t i = 0; worktrees[i]; i++)
9696
ret |= refs_fsck(get_worktree_ref_store(worktrees[i]),
9797
&fsck_refs_options, worktrees[i]);

fsck.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ enum fsck_msg_type {
3030
FUNC(BAD_EMAIL, ERROR) \
3131
FUNC(BAD_NAME, ERROR) \
3232
FUNC(BAD_OBJECT_SHA1, ERROR) \
33+
FUNC(BAD_PACKED_REF_ENTRY, ERROR) \
34+
FUNC(BAD_PACKED_REF_HEADER, ERROR) \
3335
FUNC(BAD_PARENT_SHA1, ERROR) \
3436
FUNC(BAD_REF_CONTENT, ERROR) \
3537
FUNC(BAD_REF_FILETYPE, ERROR) \
@@ -53,6 +55,8 @@ enum fsck_msg_type {
5355
FUNC(MISSING_TYPE, ERROR) \
5456
FUNC(MISSING_TYPE_ENTRY, ERROR) \
5557
FUNC(MULTIPLE_AUTHORS, ERROR) \
58+
FUNC(PACKED_REF_ENTRY_NOT_TERMINATED, ERROR) \
59+
FUNC(PACKED_REF_UNSORTED, ERROR) \
5660
FUNC(TREE_NOT_SORTED, ERROR) \
5761
FUNC(UNKNOWN_TYPE, ERROR) \
5862
FUNC(ZERO_PADDED_DATE, ERROR) \

0 commit comments

Comments
 (0)