Skip to content

Commit c1cf918

Browse files
shejialuogitster
authored andcommitted
builtin/fsck: add git refs verify child process
At now, we have already implemented the ref consistency checks for both "files-backend" and "packed-backend". Although we would check some redundant things, it won't cause trouble. So, let's integrate it into the "git-fsck(1)" command to get feedback from the users. And also by calling "git refs verify" in "git-fsck(1)", we make sure that the new added checks don't break. Introduce a new function "fsck_refs" that initializes and runs a child process to execute the "git refs verify" command. In order to provide the user interface create a progress which makes the total task be 1. It's hard to know how many loose refs we will check now. We might improve this later. Then, introduce the option to allow the user to disable checking ref database consistency. Put this function in the very first execution sequence of "git-fsck(1)" due to that we don't want the existing code of "git-fsck(1)" which would implicitly check the consistency of refs to die the program. Last, update the test to exercise the code. 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 e1c9548 commit c1cf918

File tree

3 files changed

+77
-2
lines changed

3 files changed

+77
-2
lines changed

Documentation/git-fsck.txt

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
@@ -902,11 +903,37 @@ static int check_pack_rev_indexes(struct repository *r, int show_progress)
902903
return res;
903904
}
904905

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

@@ -925,6 +952,7 @@ static struct option fsck_opts[] = {
925952
N_("write dangling objects in .git/lost-found")),
926953
OPT_BOOL(0, "progress", &show_progress, N_("show progress")),
927954
OPT_BOOL(0, "name-objects", &name_objects, N_("show verbose names for reachable objects")),
955+
OPT_BOOL(0, "references", &check_references, N_("check reference database consistency")),
928956
OPT_END(),
929957
};
930958

@@ -967,6 +995,9 @@ int cmd_fsck(int argc,
967995
git_config(git_fsck_config, &fsck_obj_options);
968996
prepare_repo_settings(the_repository);
969997

998+
if (check_references)
999+
fsck_refs(the_repository);
1000+
9701001
if (connectivity_only) {
9711002
for_each_loose_object(mark_loose_for_connectivity, NULL, 0);
9721003
for_each_packed_object(the_repository,

t/t0602-reffiles-fsck.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,4 +830,43 @@ test_expect_success 'packed-ref without sorted trait should not be checked' '
830830
)
831831
'
832832

833+
test_expect_success '--[no-]references option should apply to fsck' '
834+
test_when_finished "rm -rf repo" &&
835+
git init repo &&
836+
branch_dir_prefix=.git/refs/heads &&
837+
(
838+
cd repo &&
839+
test_commit default &&
840+
for trailing_content in " garbage" " more garbage"
841+
do
842+
printf "%s" "$(git rev-parse HEAD)$trailing_content" >$branch_dir_prefix/branch-garbage &&
843+
git fsck 2>err &&
844+
cat >expect <<-EOF &&
845+
warning: refs/heads/branch-garbage: trailingRefContent: has trailing garbage: '\''$trailing_content'\''
846+
EOF
847+
rm $branch_dir_prefix/branch-garbage &&
848+
test_cmp expect err || return 1
849+
done &&
850+
851+
for trailing_content in " garbage" " more garbage"
852+
do
853+
printf "%s" "$(git rev-parse HEAD)$trailing_content" >$branch_dir_prefix/branch-garbage &&
854+
git fsck --references 2>err &&
855+
cat >expect <<-EOF &&
856+
warning: refs/heads/branch-garbage: trailingRefContent: has trailing garbage: '\''$trailing_content'\''
857+
EOF
858+
rm $branch_dir_prefix/branch-garbage &&
859+
test_cmp expect err || return 1
860+
done &&
861+
862+
for trailing_content in " garbage" " more garbage"
863+
do
864+
printf "%s" "$(git rev-parse HEAD)$trailing_content" >$branch_dir_prefix/branch-garbage &&
865+
git fsck --no-references 2>err &&
866+
rm $branch_dir_prefix/branch-garbage &&
867+
test_must_be_empty err || return 1
868+
done
869+
)
870+
'
871+
833872
test_done

0 commit comments

Comments
 (0)