ref: check the full refname instead of basename
In "files-backend.c::files_fsck_refs_name", we validate the refname format by using "check_refname_format" to check the basename of the iterator with "REFNAME_ALLOW_ONELEVEL" flag. However, this is a bad implementation. Although we doesn't allow a single "@" in ".git" directory, we do allow "refs/heads/@". So, we will report an error wrongly when there is a "refs/heads/@" ref by using one level refname "@". Because we just check one level refname, we either cannot check the other parts of the full refname. And we will ignore the following errors: "refs/heads/ new-feature/test" "refs/heads/~new-feature/test" In order to fix the above problem, enhance "files_fsck_refs_name" to use the full name for "check_refname_format". Then, replace the tests which are related to "@" and add tests to exercise the above situations using for loop to avoid repetition. Mentored-by: Patrick Steinhardt <ps@pks.im> Mentored-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: shejialuo <shejialuo@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
38cd6eead1
commit
32dc1c7ec3
@ -3519,10 +3519,13 @@ static int files_fsck_refs_name(struct ref_store *ref_store UNUSED,
|
|||||||
if (iter->basename[0] != '.' && ends_with(iter->basename, ".lock"))
|
if (iter->basename[0] != '.' && ends_with(iter->basename, ".lock"))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (check_refname_format(iter->basename, REFNAME_ALLOW_ONELEVEL)) {
|
/*
|
||||||
|
* This works right now because we never check the root refs.
|
||||||
|
*/
|
||||||
|
strbuf_addf(&sb, "%s/%s", refs_check_dir, iter->relative_path);
|
||||||
|
if (check_refname_format(sb.buf, 0)) {
|
||||||
struct fsck_ref_report report = { 0 };
|
struct fsck_ref_report report = { 0 };
|
||||||
|
|
||||||
strbuf_addf(&sb, "%s/%s", refs_check_dir, iter->relative_path);
|
|
||||||
report.path = sb.buf;
|
report.path = sb.buf;
|
||||||
ret = fsck_report_ref(o, &report,
|
ret = fsck_report_ref(o, &report,
|
||||||
FSCK_MSG_BAD_REF_NAME,
|
FSCK_MSG_BAD_REF_NAME,
|
||||||
|
@ -18,63 +18,81 @@ test_expect_success 'ref name should be checked' '
|
|||||||
cd repo &&
|
cd repo &&
|
||||||
|
|
||||||
git commit --allow-empty -m initial &&
|
git commit --allow-empty -m initial &&
|
||||||
git checkout -b branch-1 &&
|
git checkout -b default-branch &&
|
||||||
git tag tag-1 &&
|
git tag default-tag &&
|
||||||
git commit --allow-empty -m second &&
|
git tag multi_hierarchy/default-tag &&
|
||||||
git checkout -b branch-2 &&
|
|
||||||
git tag tag-2 &&
|
|
||||||
git tag multi_hierarchy/tag-2 &&
|
|
||||||
|
|
||||||
cp $branch_dir_prefix/branch-1 $branch_dir_prefix/.branch-1 &&
|
cp $branch_dir_prefix/default-branch $branch_dir_prefix/@ &&
|
||||||
test_must_fail git refs verify 2>err &&
|
git refs verify 2>err &&
|
||||||
cat >expect <<-EOF &&
|
test_must_be_empty err &&
|
||||||
error: refs/heads/.branch-1: badRefName: invalid refname format
|
|
||||||
EOF
|
|
||||||
rm $branch_dir_prefix/.branch-1 &&
|
|
||||||
test_cmp expect err &&
|
|
||||||
|
|
||||||
cp $branch_dir_prefix/branch-1 $branch_dir_prefix/@ &&
|
|
||||||
test_must_fail git refs verify 2>err &&
|
|
||||||
cat >expect <<-EOF &&
|
|
||||||
error: refs/heads/@: badRefName: invalid refname format
|
|
||||||
EOF
|
|
||||||
rm $branch_dir_prefix/@ &&
|
rm $branch_dir_prefix/@ &&
|
||||||
test_cmp expect err &&
|
|
||||||
|
|
||||||
cp $tag_dir_prefix/multi_hierarchy/tag-2 $tag_dir_prefix/multi_hierarchy/@ &&
|
cp $tag_dir_prefix/default-tag $tag_dir_prefix/tag-1.lock &&
|
||||||
test_must_fail git refs verify 2>err &&
|
|
||||||
cat >expect <<-EOF &&
|
|
||||||
error: refs/tags/multi_hierarchy/@: badRefName: invalid refname format
|
|
||||||
EOF
|
|
||||||
rm $tag_dir_prefix/multi_hierarchy/@ &&
|
|
||||||
test_cmp expect err &&
|
|
||||||
|
|
||||||
cp $tag_dir_prefix/tag-1 $tag_dir_prefix/tag-1.lock &&
|
|
||||||
git refs verify 2>err &&
|
git refs verify 2>err &&
|
||||||
rm $tag_dir_prefix/tag-1.lock &&
|
rm $tag_dir_prefix/tag-1.lock &&
|
||||||
test_must_be_empty err &&
|
test_must_be_empty err &&
|
||||||
|
|
||||||
cp $tag_dir_prefix/tag-1 $tag_dir_prefix/.lock &&
|
cp $tag_dir_prefix/default-tag $tag_dir_prefix/.lock &&
|
||||||
test_must_fail git refs verify 2>err &&
|
test_must_fail git refs verify 2>err &&
|
||||||
cat >expect <<-EOF &&
|
cat >expect <<-EOF &&
|
||||||
error: refs/tags/.lock: badRefName: invalid refname format
|
error: refs/tags/.lock: badRefName: invalid refname format
|
||||||
EOF
|
EOF
|
||||||
rm $tag_dir_prefix/.lock &&
|
rm $tag_dir_prefix/.lock &&
|
||||||
test_cmp expect err
|
test_cmp expect err &&
|
||||||
|
|
||||||
|
for refname in ".refname-starts-with-dot" "~refname-has-stride"
|
||||||
|
do
|
||||||
|
cp $branch_dir_prefix/default-branch "$branch_dir_prefix/$refname" &&
|
||||||
|
test_must_fail git refs verify 2>err &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
error: refs/heads/$refname: badRefName: invalid refname format
|
||||||
|
EOF
|
||||||
|
rm "$branch_dir_prefix/$refname" &&
|
||||||
|
test_cmp expect err || return 1
|
||||||
|
done &&
|
||||||
|
|
||||||
|
for refname in ".refname-starts-with-dot" "~refname-has-stride"
|
||||||
|
do
|
||||||
|
cp $tag_dir_prefix/default-tag "$tag_dir_prefix/$refname" &&
|
||||||
|
test_must_fail git refs verify 2>err &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
error: refs/tags/$refname: badRefName: invalid refname format
|
||||||
|
EOF
|
||||||
|
rm "$tag_dir_prefix/$refname" &&
|
||||||
|
test_cmp expect err || return 1
|
||||||
|
done &&
|
||||||
|
|
||||||
|
for refname in ".refname-starts-with-dot" "~refname-has-stride"
|
||||||
|
do
|
||||||
|
cp $tag_dir_prefix/multi_hierarchy/default-tag "$tag_dir_prefix/multi_hierarchy/$refname" &&
|
||||||
|
test_must_fail git refs verify 2>err &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
error: refs/tags/multi_hierarchy/$refname: badRefName: invalid refname format
|
||||||
|
EOF
|
||||||
|
rm "$tag_dir_prefix/multi_hierarchy/$refname" &&
|
||||||
|
test_cmp expect err || return 1
|
||||||
|
done &&
|
||||||
|
|
||||||
|
for refname in ".refname-starts-with-dot" "~refname-has-stride"
|
||||||
|
do
|
||||||
|
mkdir "$branch_dir_prefix/$refname" &&
|
||||||
|
cp $branch_dir_prefix/default-branch "$branch_dir_prefix/$refname/default-branch" &&
|
||||||
|
test_must_fail git refs verify 2>err &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
error: refs/heads/$refname/default-branch: badRefName: invalid refname format
|
||||||
|
EOF
|
||||||
|
rm -r "$branch_dir_prefix/$refname" &&
|
||||||
|
test_cmp expect err || return 1
|
||||||
|
done
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'ref name check should be adapted into fsck messages' '
|
test_expect_success 'ref name check should be adapted into fsck messages' '
|
||||||
test_when_finished "rm -rf repo" &&
|
test_when_finished "rm -rf repo" &&
|
||||||
git init repo &&
|
git init repo &&
|
||||||
branch_dir_prefix=.git/refs/heads &&
|
branch_dir_prefix=.git/refs/heads &&
|
||||||
tag_dir_prefix=.git/refs/tags &&
|
|
||||||
cd repo &&
|
cd repo &&
|
||||||
git commit --allow-empty -m initial &&
|
git commit --allow-empty -m initial &&
|
||||||
git checkout -b branch-1 &&
|
git checkout -b branch-1 &&
|
||||||
git tag tag-1 &&
|
|
||||||
git commit --allow-empty -m second &&
|
|
||||||
git checkout -b branch-2 &&
|
|
||||||
git tag tag-2 &&
|
|
||||||
|
|
||||||
cp $branch_dir_prefix/branch-1 $branch_dir_prefix/.branch-1 &&
|
cp $branch_dir_prefix/branch-1 $branch_dir_prefix/.branch-1 &&
|
||||||
git -c fsck.badRefName=warn refs verify 2>err &&
|
git -c fsck.badRefName=warn refs verify 2>err &&
|
||||||
@ -84,7 +102,7 @@ test_expect_success 'ref name check should be adapted into fsck messages' '
|
|||||||
rm $branch_dir_prefix/.branch-1 &&
|
rm $branch_dir_prefix/.branch-1 &&
|
||||||
test_cmp expect err &&
|
test_cmp expect err &&
|
||||||
|
|
||||||
cp $branch_dir_prefix/branch-1 $branch_dir_prefix/@ &&
|
cp $branch_dir_prefix/branch-1 $branch_dir_prefix/.branch-1 &&
|
||||||
git -c fsck.badRefName=ignore refs verify 2>err &&
|
git -c fsck.badRefName=ignore refs verify 2>err &&
|
||||||
test_must_be_empty err
|
test_must_be_empty err
|
||||||
'
|
'
|
||||||
|
Reference in New Issue
Block a user