aboutsummaryrefslogtreecommitdiff
path: root/refs.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2026-01-21 08:28:58 -0800
committerJunio C Hamano <gitster@pobox.com>2026-01-21 08:28:58 -0800
commitdc861c97c3ddecbc1dcee0c310de12ad8af97ef8 (patch)
tree5dbb06e504433cbdb3fede46c1b90674efcfa48d /refs.c
parent0a5dcc1259fa0c8f5c21352c90b3cd3d43273345 (diff)
parent8947da018387f146a90e64055b4caf2ab79e39a7 (diff)
downloadgit-dc861c97c3ddecbc1dcee0c310de12ad8af97ef8.tar.xz
Merge branch 'ps/ref-consistency-checks'
Update code paths that check data integrity around refs subsystem. cf. <CAOLa=ZShPP3BPXa=YnC-vuX4zF=pUTFdUidZwOdna8bfVTNM9w@mail.gmail.com> * ps/ref-consistency-checks: builtin/fsck: drop `fsck_head_link()` builtin/fsck: move generic HEAD check into `refs_fsck()` builtin/fsck: move generic object ID checks into `refs_fsck()` refs/reftable: introduce generic checks for refs refs/reftable: fix consistency checks with worktrees refs/reftable: extract function to retrieve backend for worktree refs/reftable: adapt includes to become consistent refs/files: introduce function to perform normal ref checks refs/files: extract generic symref target checks fsck: drop unused fields from `struct fsck_ref_report` refs/files: perform consistency checks for root refs refs/files: improve error handling when verifying symrefs refs/files: extract function to check single ref refs/files: remove useless indirection refs/files: remove `refs_check_dir` parameter refs/files: move fsck functions into global scope refs/files: simplify iterating through root refs
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/refs.c b/refs.c
index 046b695bb2..627b7f8698 100644
--- a/refs.c
+++ b/refs.c
@@ -320,6 +320,49 @@ int check_refname_format(const char *refname, int flags)
return check_or_sanitize_refname(refname, flags, NULL);
}
+int refs_fsck_ref(struct ref_store *refs UNUSED, struct fsck_options *o,
+ struct fsck_ref_report *report,
+ const char *refname UNUSED, const struct object_id *oid)
+{
+ if (is_null_oid(oid))
+ return fsck_report_ref(o, report, FSCK_MSG_BAD_REF_OID,
+ "points to invalid object ID '%s'",
+ oid_to_hex(oid));
+
+ return 0;
+}
+
+int refs_fsck_symref(struct ref_store *refs UNUSED, struct fsck_options *o,
+ struct fsck_ref_report *report,
+ 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;
+
+ if (check_refname_format(target, 0) &&
+ fsck_report_ref(o, report, FSCK_MSG_BAD_REFERENT_NAME,
+ "points to invalid refname '%s'", target))
+ return -1;
+
+ if (!starts_with(target, "refs/") &&
+ !starts_with(target, "worktrees/") &&
+ fsck_report_ref(o, report, FSCK_MSG_SYMREF_TARGET_IS_NOT_A_REF,
+ "points to non-ref target '%s'", target))
+ return -1;
+
+ return 0;
+}
+
int refs_fsck(struct ref_store *refs, struct fsck_options *o,
struct worktree *wt)
{