]> git.ipfire.org Git - thirdparty/git.git/commitdiff
builtin/fsck: move generic HEAD check into `refs_fsck()`
authorPatrick Steinhardt <ps@pks.im>
Mon, 12 Jan 2026 09:03:05 +0000 (10:03 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 12 Jan 2026 14:55:41 +0000 (06:55 -0800)
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 <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/fsck-msgids.adoc
builtin/fsck.c
fsck.h
refs.c
t/t0602-reffiles-fsck.sh
t/t1450-fsck.sh

index 76609321f662dd957f9c61b6029be44c0dc1002c..6a4db3a9916ea6c74f89027f1b075f6443f72bb8 100644 (file)
@@ -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.
 
index 4dd4d74d1e15da041dc35187131dd9d226ac970c..5dda441f45f3f55bba01160438466e559386ba7f 100644 (file)
@@ -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 1f472b7daac38cba6f2c29f999e3a636c1044975..65ecbb7fe194ab5beceb81383b2f219b012b8395 100644 (file)
--- 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 c3528862c68f63a359323c4b22095026c4c4fbd5..a772d371cd593859afeb669236f05b594103370c 100644 (file)
--- 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;
 
index 479f3d528e6ca82ae802112cd197d47df8a9c141..3c1f553b8120ec6d8de641696e85c3cb79191f6a 100755 (executable)
@@ -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
        )
index 900c1b2eb258c14a107ea0bf0f80be79b2ca895f..3fae05f9d9f805d86d04ac3ecebd60b16cce80f6 100755 (executable)
@@ -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' '