]> git.ipfire.org Git - thirdparty/git.git/commitdiff
refs: add a `optimize_required` field to `struct ref_storage_be`
authorKarthik Nayak <karthik.188@gmail.com>
Thu, 6 Nov 2025 08:22:32 +0000 (09:22 +0100)
committerJunio C Hamano <gitster@pobox.com>
Thu, 6 Nov 2025 18:00:07 +0000 (10:00 -0800)
To allow users of the refs namespace to check if the reference backend
requires optimization, add a new field `optimize_required` field to
`struct ref_storage_be`. This field is of type `optimize_required_fn`
which is also introduced in this commit.

Modify the debug, files, packed and reftable backend to implement this
field. A following commit will expose this via 'git pack-refs' and 'git
refs optimize'.

Signed-off-by: Karthik Nayak <karthik.188@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 0d0831f29ba25bccae36170e9dcfef27f623904e..5583f6e09d7c76c132b91d3211d09d0838180c03 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -2318,6 +2318,13 @@ int refs_optimize(struct ref_store *refs, struct refs_optimize_opts *opts)
        return refs->be->optimize(refs, opts);
 }
 
+int refs_optimize_required(struct ref_store *refs,
+                          struct refs_optimize_opts *opts,
+                          bool *required)
+{
+       return refs->be->optimize_required(refs, opts, required);
+}
+
 int reference_get_peeled_oid(struct repository *repo,
                             const struct reference *ref,
                             struct object_id *peeled_oid)
diff --git a/refs.h b/refs.h
index 6b05bba527ffca938a75b1e1d98ee0f608d54234..d9051bbb0414c2f70c61b898f1ef1b500b7cb390 100644 (file)
--- a/refs.h
+++ b/refs.h
@@ -520,6 +520,13 @@ struct refs_optimize_opts {
  */
 int refs_optimize(struct ref_store *refs, struct refs_optimize_opts *opts);
 
+/*
+ * Check if refs backend can be optimized by calling 'refs_optimize'.
+ */
+int refs_optimize_required(struct ref_store *ref_store,
+                          struct refs_optimize_opts *opts,
+                          bool *required);
+
 /*
  * Setup reflog before using. Fill in err and return -1 on failure.
  */
index 2defd2d465712ef3d8a0721c2b837084a9c029d2..36f8c58b6c781f1d35357a25731337285faa125b 100644 (file)
@@ -124,6 +124,17 @@ static int debug_optimize(struct ref_store *ref_store, struct refs_optimize_opts
        return res;
 }
 
+static int debug_optimize_required(struct ref_store *ref_store,
+                                  struct refs_optimize_opts *opts,
+                                  bool *required)
+{
+       struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
+       int res = drefs->refs->be->optimize_required(drefs->refs, opts, required);
+       trace_printf_key(&trace_refs, "optimize_required: %s, res: %d\n",
+                        required ? "yes" : "no", res);
+       return res;
+}
+
 static int debug_rename_ref(struct ref_store *ref_store, const char *oldref,
                            const char *newref, const char *logmsg)
 {
@@ -431,6 +442,8 @@ struct ref_storage_be refs_be_debug = {
        .transaction_abort = debug_transaction_abort,
 
        .optimize = debug_optimize,
+       .optimize_required = debug_optimize_required,
+
        .rename_ref = debug_rename_ref,
        .copy_ref = debug_copy_ref,
 
index a1e70b1c10dbb81ec48727018b840d7677065f64..6e0c9b340a0f6f6d9b324d41c0ff1508f15cb3ac 100644 (file)
@@ -1512,6 +1512,16 @@ static int files_optimize(struct ref_store *ref_store,
        return 0;
 }
 
+static int files_optimize_required(struct ref_store *ref_store,
+                                  struct refs_optimize_opts *opts,
+                                  bool *required)
+{
+       struct files_ref_store *refs = files_downcast(ref_store, REF_STORE_READ,
+                                                     "optimize_required");
+       *required = should_pack_refs(refs, opts);
+       return 0;
+}
+
 /*
  * People using contrib's git-new-workdir have .git/logs/refs ->
  * /some/other/path/.git/logs/refs, and that may live on another device.
@@ -3982,6 +3992,7 @@ struct ref_storage_be refs_be_files = {
        .transaction_abort = files_transaction_abort,
 
        .optimize = files_optimize,
+       .optimize_required = files_optimize_required,
        .rename_ref = files_rename_ref,
        .copy_ref = files_copy_ref,
 
index 10062fd8b63063795266fb7dc0805ecdf43ac6a4..19ce4d58728e8c121c813ae893059bd7cc0d4803 100644 (file)
@@ -1784,6 +1784,17 @@ static int packed_optimize(struct ref_store *ref_store UNUSED,
        return 0;
 }
 
+static int packed_optimize_required(struct ref_store *ref_store UNUSED,
+                                   struct refs_optimize_opts *opts UNUSED,
+                                   bool *required)
+{
+       /*
+        * Packed refs are already optimized.
+        */
+       *required = false;
+       return 0;
+}
+
 static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_store UNUSED)
 {
        return empty_ref_iterator_begin();
@@ -2130,6 +2141,8 @@ struct ref_storage_be refs_be_packed = {
        .transaction_abort = packed_transaction_abort,
 
        .optimize = packed_optimize,
+       .optimize_required = packed_optimize_required,
+
        .rename_ref = NULL,
        .copy_ref = NULL,
 
index dee42f231dbd0a0a445bf9b31fc61a5c3d95cc7e..c7d2a6e50b7696cc3eba626a7538dcbc0dba1880 100644 (file)
@@ -424,6 +424,11 @@ typedef int ref_transaction_commit_fn(struct ref_store *refs,
 
 typedef int optimize_fn(struct ref_store *ref_store,
                        struct refs_optimize_opts *opts);
+
+typedef int optimize_required_fn(struct ref_store *ref_store,
+                                struct refs_optimize_opts *opts,
+                                bool *required);
+
 typedef int rename_ref_fn(struct ref_store *ref_store,
                          const char *oldref, const char *newref,
                          const char *logmsg);
@@ -549,6 +554,7 @@ struct ref_storage_be {
        ref_transaction_abort_fn *transaction_abort;
 
        optimize_fn *optimize;
+       optimize_required_fn *optimize_required;
        rename_ref_fn *rename_ref;
        copy_ref_fn *copy_ref;
 
index c23c45f3bf46399b4eb432f2a8c1262bb8e37cbc..a3ae0cf74a05889434248d793b442e8b4b84b976 100644 (file)
@@ -1733,6 +1733,29 @@ out:
        return ret;
 }
 
+static int reftable_be_optimize_required(struct ref_store *ref_store,
+                                        struct refs_optimize_opts *opts,
+                                        bool *required)
+{
+       struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_READ,
+                                                              "optimize_refs_required");
+       struct reftable_stack *stack;
+       bool use_heuristics = false;
+
+       if (refs->err)
+               return refs->err;
+
+       stack = refs->worktree_backend.stack;
+       if (!stack)
+               stack = refs->main_backend.stack;
+
+       if (opts->flags & REFS_OPTIMIZE_AUTO)
+               use_heuristics = true;
+
+       return reftable_stack_compaction_required(stack, use_heuristics,
+                                                 required);
+}
+
 struct write_create_symref_arg {
        struct reftable_ref_store *refs;
        struct reftable_stack *stack;
@@ -2756,6 +2779,8 @@ struct ref_storage_be refs_be_reftable = {
        .transaction_abort = reftable_be_transaction_abort,
 
        .optimize = reftable_be_optimize,
+       .optimize_required = reftable_be_optimize_required,
+
        .rename_ref = reftable_be_rename_ref,
        .copy_ref = reftable_be_copy_ref,