]> git.ipfire.org Git - thirdparty/git.git/commitdiff
object-name: move logic to iterate through loose prefixed objects
authorPatrick Steinhardt <ps@pks.im>
Fri, 20 Mar 2026 07:07:30 +0000 (08:07 +0100)
committerJunio C Hamano <gitster@pobox.com>
Fri, 20 Mar 2026 20:16:42 +0000 (13:16 -0700)
The logic to iterate through loose objects that have a certain prefix is
currently hosted in "object-name.c". This logic reaches into specifics
of the loose object source, so it breaks once a different backend is
used for the object storage.

Move the logic to iterate through loose objects with a prefix into
"object-file.c". This is done by extending the for-each-object options
to support an optional prefix that is then honored by the loose source.
Naturally, we'll also have this support in the packfile store. This is
done in the next commit.

Furthermore, there are no users of the loose cache outside of
"object-file.c" anymore. As such, convert `odb_source_loose_cache()` to
have file scope.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file.c
object-file.h
object-name.c
odb.h

index 56cbb27ab908a80c7391e5da009391417eb7b9cd..13732f324f5bccfe84d2575d3da0fd13921dcef7 100644 (file)
@@ -33,6 +33,9 @@
 /* The maximum size for an object header. */
 #define MAX_HEADER_LEN 32
 
+static struct oidtree *odb_source_loose_cache(struct odb_source *source,
+                                             const struct object_id *oid);
+
 static int get_conv_flags(unsigned flags)
 {
        if (flags & INDEX_RENORMALIZE)
@@ -1845,6 +1848,23 @@ static int for_each_object_wrapper_cb(const struct object_id *oid,
        }
 }
 
+static int for_each_prefixed_object_wrapper_cb(const struct object_id *oid,
+                                              void *cb_data)
+{
+       struct for_each_object_wrapper_data *data = cb_data;
+       if (data->request) {
+               struct object_info oi = *data->request;
+
+               if (odb_source_loose_read_object_info(data->source,
+                                                     oid, &oi, 0) < 0)
+                       return -1;
+
+               return data->cb(oid, &oi, data->cb_data);
+       } else {
+               return data->cb(oid, NULL, data->cb_data);
+       }
+}
+
 int odb_source_loose_for_each_object(struct odb_source *source,
                                     const struct object_info *request,
                                     odb_for_each_object_cb cb,
@@ -1864,6 +1884,11 @@ int odb_source_loose_for_each_object(struct odb_source *source,
        if ((opts->flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY) && !source->local)
                return 0;
 
+       if (opts->prefix)
+               return oidtree_each(odb_source_loose_cache(source, opts->prefix),
+                                   opts->prefix, opts->prefix_hex_len,
+                                   for_each_prefixed_object_wrapper_cb, &data);
+
        return for_each_loose_file_in_source(source, for_each_object_wrapper_cb,
                                             NULL, NULL, &data);
 }
@@ -1935,8 +1960,8 @@ static int append_loose_object(const struct object_id *oid,
        return 0;
 }
 
-struct oidtree *odb_source_loose_cache(struct odb_source *source,
-                                      const struct object_id *oid)
+static struct oidtree *odb_source_loose_cache(struct odb_source *source,
+                                             const struct object_id *oid)
 {
        struct odb_source_files *files = odb_source_files_downcast(source);
        int subdir_nr = oid->hash[0];
index 46dfa7b632b334d556cdbe795f508b10032f03a9..f11ad58f6c08745c84054a9af0a9b5e07699ec95 100644 (file)
@@ -74,13 +74,6 @@ int odb_source_loose_write_stream(struct odb_source *source,
                                  struct odb_write_stream *stream, size_t len,
                                  struct object_id *oid);
 
-/*
- * Populate and return the loose object cache array corresponding to the
- * given object ID.
- */
-struct oidtree *odb_source_loose_cache(struct odb_source *source,
-                                      const struct object_id *oid);
-
 /*
  * Put in `buf` the name of the file in the local object database that
  * would be used to store a loose object with the specified oid.
index a24a1b48e12ae91716d7048ceebe68c994b4c098..929a68dbd0d32bebe6239cf8016867839a0d47be 100644 (file)
@@ -16,7 +16,6 @@
 #include "remote.h"
 #include "dir.h"
 #include "oid-array.h"
-#include "oidtree.h"
 #include "packfile.h"
 #include "pretty.h"
 #include "object-file.h"
@@ -103,7 +102,7 @@ static void update_candidates(struct disambiguate_state *ds, const struct object
 
 static int match_hash(unsigned, const unsigned char *, const unsigned char *);
 
-static int match_prefix(const struct object_id *oid, void *arg)
+static int match_prefix(const struct object_id *oid, struct object_info *oi UNUSED, void *arg)
 {
        struct disambiguate_state *ds = arg;
        /* no need to call match_hash, oidtree_each did prefix match */
@@ -113,11 +112,14 @@ static int match_prefix(const struct object_id *oid, void *arg)
 
 static void find_short_object_filename(struct disambiguate_state *ds)
 {
+       struct odb_for_each_object_options opts = {
+               .prefix = &ds->bin_pfx,
+               .prefix_hex_len = ds->len,
+       };
        struct odb_source *source;
 
        for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next)
-               oidtree_each(odb_source_loose_cache(source, &ds->bin_pfx),
-                               &ds->bin_pfx, ds->len, match_prefix, ds);
+               odb_source_loose_for_each_object(source, NULL, match_prefix, ds, &opts);
 }
 
 static int match_hash(unsigned len, const unsigned char *a, const unsigned char *b)
diff --git a/odb.h b/odb.h
index a19a8bb50d86e78a85fa2c811464f2fef0b58813..e80fd8f7abd534de757efcd1c272a486e9c8445d 100644 (file)
--- a/odb.h
+++ b/odb.h
@@ -488,6 +488,13 @@ typedef int (*odb_for_each_object_cb)(const struct object_id *oid,
 struct odb_for_each_object_options {
        /* A bitfield of `odb_for_each_object_flags`. */
        enum odb_for_each_object_flags flags;
+
+       /*
+        * If set, only iterate through objects whose first `prefix_hex_len`
+        * hex characters matches the given prefix.
+        */
+       const struct object_id *prefix;
+       size_t prefix_hex_len;
 };
 
 /*