From b2f2a58a256f65716fccf7484662f1c56764a285 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 9 Jan 2026 13:39:45 +0100 Subject: [PATCH] builtin/fsck: move generic HEAD check into `refs_fsck()` Move the check that detects "HEAD" refs that do not point at a branch into `refs_fsck()`. This follows the same motivation as the preceding commit. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- Documentation/fsck-msgids.adoc | 3 +++ builtin/fsck.c | 7 ------- fsck.h | 1 + refs.c | 12 +++++++++++- t/t0602-reffiles-fsck.sh | 8 ++++---- t/t1450-fsck.sh | 4 ++-- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/Documentation/fsck-msgids.adoc b/Documentation/fsck-msgids.adoc index 76609321f6..6a4db3a991 100644 --- a/Documentation/fsck-msgids.adoc +++ b/Documentation/fsck-msgids.adoc @@ -13,6 +13,9 @@ `badGpgsig`:: (ERROR) A tag contains a bad (truncated) signature (e.g., `gpgsig`) header. +`badHeadTarget`:: + (ERROR) The `HEAD` ref is a symref that does not refer to a branch. + `badHeaderContinuation`:: (ERROR) A continuation header (such as for `gpgsig`) is unexpectedly truncated. diff --git a/builtin/fsck.c b/builtin/fsck.c index 4dd4d74d1e..5dda441f45 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -728,13 +728,6 @@ static void fsck_head_link(const char *head_ref_name, error(_("invalid %s"), head_ref_name); return; } - if (strcmp(*head_points_at, head_ref_name) && - !starts_with(*head_points_at, "refs/heads/")) { - errors_found |= ERROR_REFS; - error(_("%s points to something strange (%s)"), - head_ref_name, *head_points_at); - return; - } return; } diff --git a/fsck.h b/fsck.h index 1f472b7daa..65ecbb7fe1 100644 --- a/fsck.h +++ b/fsck.h @@ -30,6 +30,7 @@ enum fsck_msg_type { FUNC(BAD_DATE_OVERFLOW, ERROR) \ FUNC(BAD_EMAIL, ERROR) \ FUNC(BAD_GPGSIG, ERROR) \ + FUNC(BAD_HEAD_TARGET, ERROR) \ FUNC(BAD_NAME, ERROR) \ FUNC(BAD_OBJECT_SHA1, ERROR) \ FUNC(BAD_PACKED_REF_ENTRY, ERROR) \ diff --git a/refs.c b/refs.c index c3528862c6..a772d371cd 100644 --- a/refs.c +++ b/refs.c @@ -334,8 +334,18 @@ int refs_fsck_ref(struct ref_store *refs UNUSED, struct fsck_options *o, int refs_fsck_symref(struct ref_store *refs UNUSED, struct fsck_options *o, struct fsck_ref_report *report, - const char *refname UNUSED, const char *target) + const char *refname, const char *target) { + const char *stripped_refname; + + parse_worktree_ref(refname, NULL, NULL, &stripped_refname); + + if (!strcmp(stripped_refname, "HEAD") && + !starts_with(target, "refs/heads/") && + fsck_report_ref(o, report, FSCK_MSG_BAD_HEAD_TARGET, + "HEAD points to non-branch '%s'", target)) + return -1; + if (is_root_ref(target)) return 0; diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh index 479f3d528e..3c1f553b81 100755 --- a/t/t0602-reffiles-fsck.sh +++ b/t/t0602-reffiles-fsck.sh @@ -910,10 +910,10 @@ test_expect_success 'complains about broken root ref' ' git init repo && ( cd repo && - echo "ref: refs/../HEAD" >.git/HEAD && + echo "ref: refs/heads/../HEAD" >.git/HEAD && test_must_fail git refs verify 2>err && cat >expect <<-EOF && - error: HEAD: badReferentName: points to invalid refname ${SQ}refs/../HEAD${SQ} + error: HEAD: badReferentName: points to invalid refname ${SQ}refs/heads/../HEAD${SQ} EOF test_cmp expect err ) @@ -926,10 +926,10 @@ test_expect_success 'complains about broken root ref in worktree' ' cd repo && test_commit initial && git worktree add ../worktree && - echo "ref: refs/../HEAD" >.git/worktrees/worktree/HEAD && + echo "ref: refs/heads/../HEAD" >.git/worktrees/worktree/HEAD && test_must_fail git refs verify 2>err && cat >expect <<-EOF && - error: worktrees/worktree/HEAD: badReferentName: points to invalid refname ${SQ}refs/../HEAD${SQ} + error: worktrees/worktree/HEAD: badReferentName: points to invalid refname ${SQ}refs/heads/../HEAD${SQ} EOF test_cmp expect err ) diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 900c1b2eb2..3fae05f9d9 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -113,7 +113,7 @@ test_expect_success 'HEAD link pointing at a funny place' ' test-tool ref-store main create-symref HEAD refs/funny/place && # avoid corrupt/broken HEAD from interfering with repo discovery test_must_fail env GIT_DIR=.git git fsck 2>out && - test_grep "HEAD points to something strange" out + test_grep "HEAD: badHeadTarget: HEAD points to non-branch ${SQ}refs/funny/place${SQ}" out ' test_expect_success REFFILES 'HEAD link pointing at a funny object (from different wt)' ' @@ -148,7 +148,7 @@ test_expect_success 'other worktree HEAD link pointing at a funny place' ' git worktree add other && git -C other symbolic-ref HEAD refs/funny/place && test_must_fail git fsck 2>out && - test_grep "worktrees/other/HEAD points to something strange" out + test_grep "worktrees/other/HEAD: badHeadTarget: HEAD points to non-branch ${SQ}refs/funny/place${SQ}" out ' test_expect_success 'commit with multiple signatures is okay' '