]> git.ipfire.org Git - thirdparty/git.git/commitdiff
refs: set up ref consistency check infrastructure
authorshejialuo <shejialuo@gmail.com>
Thu, 8 Aug 2024 11:27:17 +0000 (19:27 +0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 8 Aug 2024 16:36:53 +0000 (09:36 -0700)
The "struct ref_store" is the base class which contains the "be" pointer
which provides backend-specific functions whose interfaces are defined
in the "ref_storage_be". We could reuse this polymorphism to define only
one interface. For every backend, we need to provide its own function
pointer.

The interfaces defined in the `ref_storage_be` are carefully structured
in semantic. It's organized as the five parts:

1. The name and the initialization interfaces.
2. The ref transaction interfaces.
3. The ref internal interfaces (pack, rename and copy).
4. The ref filesystem interfaces.
5. The reflog related interfaces.

To keep consistent with the git-fsck(1), add a new interface named
"fsck_refs_fn" to the end of "ref_storage_be". This semantic cannot be
grouped into any above five categories. Explicitly add blank line to
make it different from others.

Last, implement placeholder functions for each ref backends.

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>
refs.c
refs.h
refs/debug.c
refs/files-backend.c
refs/packed-backend.c
refs/refs-internal.h
refs/reftable-backend.c

diff --git a/refs.c b/refs.c
index 915aeb4d1dbb62ebc113188e83076b908f3b2c35..6f642dc681785b1d21f9dfb1dfc09dcbdb763b77 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -318,6 +318,11 @@ int check_refname_format(const char *refname, int flags)
        return check_or_sanitize_refname(refname, flags, NULL);
 }
 
+int refs_fsck(struct ref_store *refs, struct fsck_options *o)
+{
+       return refs->be->fsck(refs, o);
+}
+
 void sanitize_refname_component(const char *refname, struct strbuf *out)
 {
        if (check_or_sanitize_refname(refname, REFNAME_ALLOW_ONELEVEL, out))
diff --git a/refs.h b/refs.h
index b3e39bc257046d9672d2fdafb50e2e05c76f4bee..405073621a7179c41058ae1dada550f8af3319f2 100644 (file)
--- a/refs.h
+++ b/refs.h
@@ -4,6 +4,7 @@
 #include "commit.h"
 #include "repository.h"
 
+struct fsck_options;
 struct object_id;
 struct ref_store;
 struct strbuf;
@@ -541,6 +542,13 @@ int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_dat
  */
 int check_refname_format(const char *refname, int flags);
 
+/*
+ * Check the reference database for consistency. Return 0 if refs and
+ * reflogs are consistent, and non-zero otherwise. The errors will be
+ * written to stderr.
+ */
+int refs_fsck(struct ref_store *refs, struct fsck_options *o);
+
 /*
  * Apply the rules from check_refname_format, but mutate the result until it
  * is acceptable, and place the result in "out".
index 547d9245b98af92361903231887784a2e4467b2f..45e2e784a0f8c49f492eaa9d371aa44f8c7916c3 100644 (file)
@@ -419,6 +419,15 @@ static int debug_reflog_expire(struct ref_store *ref_store, const char *refname,
        return res;
 }
 
+static int debug_fsck(struct ref_store *ref_store,
+                     struct fsck_options *o)
+{
+       struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
+       int res = drefs->refs->be->fsck(drefs->refs, o);
+       trace_printf_key(&trace_refs, "fsck: %d\n", res);
+       return res;
+}
+
 struct ref_storage_be refs_be_debug = {
        .name = "debug",
        .init = NULL,
@@ -451,4 +460,6 @@ struct ref_storage_be refs_be_debug = {
        .create_reflog = debug_create_reflog,
        .delete_reflog = debug_delete_reflog,
        .reflog_expire = debug_reflog_expire,
+
+       .fsck = debug_fsck,
 };
index aa52d9be7c77ade85967f019cf94121e7903ef20..4630eb1f802d50a69e852f41fef0b758fa95abf1 100644 (file)
@@ -3408,6 +3408,15 @@ static int files_ref_store_remove_on_disk(struct ref_store *ref_store,
        return ret;
 }
 
+static int files_fsck(struct ref_store *ref_store,
+                     struct fsck_options *o)
+{
+       struct files_ref_store *refs =
+               files_downcast(ref_store, REF_STORE_READ, "fsck");
+
+       return refs->packed_ref_store->be->fsck(refs->packed_ref_store, o);
+}
+
 struct ref_storage_be refs_be_files = {
        .name = "files",
        .init = files_ref_store_init,
@@ -3434,5 +3443,7 @@ struct ref_storage_be refs_be_files = {
        .reflog_exists = files_reflog_exists,
        .create_reflog = files_create_reflog,
        .delete_reflog = files_delete_reflog,
-       .reflog_expire = files_reflog_expire
+       .reflog_expire = files_reflog_expire,
+
+       .fsck = files_fsck,
 };
index a0666407cdff3ce8cd46f63c875f40d22d05e9e6..5209b0b21226b0e50521540751b96ec9a92c84d4 100644 (file)
@@ -1735,6 +1735,12 @@ static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_s
        return empty_ref_iterator_begin();
 }
 
+static int packed_fsck(struct ref_store *ref_store,
+                      struct fsck_options *o)
+{
+       return 0;
+}
+
 struct ref_storage_be refs_be_packed = {
        .name = "packed",
        .init = packed_ref_store_init,
@@ -1762,4 +1768,6 @@ struct ref_storage_be refs_be_packed = {
        .create_reflog = NULL,
        .delete_reflog = NULL,
        .reflog_expire = NULL,
+
+       .fsck = packed_fsck,
 };
index fa975d69aaabad05ad5aff620f8151039da23937..a905e187cd770a80adead7a23bc59588c5f43a44 100644 (file)
@@ -4,6 +4,7 @@
 #include "refs.h"
 #include "iterator.h"
 
+struct fsck_options;
 struct ref_transaction;
 
 /*
@@ -650,6 +651,9 @@ typedef int read_raw_ref_fn(struct ref_store *ref_store, const char *refname,
 typedef int read_symbolic_ref_fn(struct ref_store *ref_store, const char *refname,
                                 struct strbuf *referent);
 
+typedef int fsck_fn(struct ref_store *ref_store,
+                   struct fsck_options *o);
+
 struct ref_storage_be {
        const char *name;
        ref_store_init_fn *init;
@@ -677,6 +681,8 @@ struct ref_storage_be {
        create_reflog_fn *create_reflog;
        delete_reflog_fn *delete_reflog;
        reflog_expire_fn *reflog_expire;
+
+       fsck_fn *fsck;
 };
 
 extern struct ref_storage_be refs_be_files;
index fbe74c239d336bf7404be6f78148a60a450eb637..b5a1a526dfda80eccd834b23c38f4d87ff91d40e 100644 (file)
@@ -2303,6 +2303,12 @@ done:
        return ret;
 }
 
+static int reftable_be_fsck(struct ref_store *ref_store,
+                           struct fsck_options *o)
+{
+       return 0;
+}
+
 struct ref_storage_be refs_be_reftable = {
        .name = "reftable",
        .init = reftable_be_init,
@@ -2330,4 +2336,6 @@ struct ref_storage_be refs_be_reftable = {
        .create_reflog = reftable_be_create_reflog,
        .delete_reflog = reftable_be_delete_reflog,
        .reflog_expire = reftable_be_reflog_expire,
+
+       .fsck = reftable_be_fsck,
 };