Skip to content

Commit b0f09d5

Browse files
shejialuogitster
authored andcommitted
packed-backend: check whether the "packed-refs" is regular file
Although "git-fsck(1)" and "packed-backend.c" will check some consistency and correctness of "packed-refs" file, they never check the filetype of the "packed-refs". The user should always use "git pack-refs" command to create the raw regular "packed-refs" file, so we need to explicitly check this in "git refs verify". We could use "open_nofollow" wrapper to open the raw "packed-refs" file. If the returned "fd" value is less than 0, we could check whether the "errno" is "ELOOP" to report an error to the user. Reuse "FSCK_MSG_BAD_REF_FILETYPE" fsck message id to report the error to the user if "packed-refs" is not a regular file. 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 e590644 commit b0f09d5

File tree

2 files changed

+57
-4
lines changed

2 files changed

+57
-4
lines changed

refs/packed-backend.c

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "../git-compat-util.h"
55
#include "../config.h"
66
#include "../dir.h"
7+
#include "../fsck.h"
78
#include "../gettext.h"
89
#include "../hash.h"
910
#include "../hex.h"
@@ -1748,15 +1749,45 @@ static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_s
17481749
return empty_ref_iterator_begin();
17491750
}
17501751

1751-
static int packed_fsck(struct ref_store *ref_store UNUSED,
1752-
struct fsck_options *o UNUSED,
1752+
static int packed_fsck(struct ref_store *ref_store,
1753+
struct fsck_options *o,
17531754
struct worktree *wt)
17541755
{
1756+
struct packed_ref_store *refs = packed_downcast(ref_store,
1757+
REF_STORE_READ, "fsck");
1758+
int ret = 0;
1759+
int fd;
17551760

17561761
if (!is_main_worktree(wt))
1757-
return 0;
1762+
goto cleanup;
17581763

1759-
return 0;
1764+
if (o->verbose)
1765+
fprintf_ln(stderr, "Checking packed-refs file %s", refs->path);
1766+
1767+
fd = open_nofollow(refs->path, O_RDONLY);
1768+
if (fd < 0) {
1769+
/*
1770+
* If the packed-refs file doesn't exist, there's nothing
1771+
* to check.
1772+
*/
1773+
if (errno == ENOENT)
1774+
goto cleanup;
1775+
1776+
if (errno == ELOOP) {
1777+
struct fsck_ref_report report = { 0 };
1778+
report.path = "packed-refs";
1779+
ret = fsck_report_ref(o, &report,
1780+
FSCK_MSG_BAD_REF_FILETYPE,
1781+
"not a regular file");
1782+
goto cleanup;
1783+
}
1784+
1785+
ret = error_errno(_("unable to open %s"), refs->path);
1786+
goto cleanup;
1787+
}
1788+
1789+
cleanup:
1790+
return ret;
17601791
}
17611792

17621793
struct ref_storage_be refs_be_packed = {

t/t0602-reffiles-fsck.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,4 +617,26 @@ test_expect_success 'ref content checks should work with worktrees' '
617617
)
618618
'
619619

620+
test_expect_success SYMLINKS 'the filetype of packed-refs should be checked' '
621+
test_when_finished "rm -rf repo" &&
622+
git init repo &&
623+
(
624+
cd repo &&
625+
test_commit default &&
626+
git branch branch-1 &&
627+
git branch branch-2 &&
628+
git branch branch-3 &&
629+
git pack-refs --all &&
630+
631+
mv .git/packed-refs .git/packed-refs-back &&
632+
ln -sf packed-refs-bak .git/packed-refs &&
633+
test_must_fail git refs verify 2>err &&
634+
cat >expect <<-EOF &&
635+
error: packed-refs: badRefFiletype: not a regular file
636+
EOF
637+
rm .git/packed-refs &&
638+
test_cmp expect err
639+
)
640+
'
641+
620642
test_done

0 commit comments

Comments
 (0)