odb/source-loose: wire up `read_object_info()` callback

Move `odb_source_loose_read_object_info()` from "object-file.c" into "odb/source-loose.c" and wire it up as the `read_object_info()` callback of the loose source. Callers that previously invoked it directly now go through the generic `odb_source_read_object_info()` interface instead. The function `read_object_info_from_path()` cannot be moved along with it because it is still called by `for_each_object_wrapper_cb()`. It is therefore kept in place, but adjusted to take a loose source to clarify that it's always operating on this structure. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jun 1, 2026 at 10:20 UTC 584338ed92735f3be768c16b53266d5bad439a7a
4 files changed +44 -39
object-file.c
+13 -33
@@ -396,13 +396,12 @@ static int parse_loose_header(const char *hdr, struct object_info *oi)
396 return 0;
397 }
398
399 -static int read_object_info_from_path(struct odb_source *source,
400 - const char *path,
401 - const struct object_id *oid,
402 - struct object_info *oi,
403 - enum object_info_flags flags)
399 +int read_object_info_from_path(struct odb_source_loose *loose,
400 + const char *path,
401 + const struct object_id *oid,
402 + struct object_info *oi,
403 + enum object_info_flags flags)
404 {
405 - struct odb_source_files *files = odb_source_files_downcast(source);
405 int ret;
406 int fd;
407 unsigned long mapsize;
@@ -425,7 +424,7 @@ static int read_object_info_from_path(struct odb_source *source,
424 struct stat st;
425
426 if ((!oi || (!oi->disk_sizep && !oi->mtimep)) && (flags & OBJECT_INFO_QUICK)) {
428 - ret = quick_has_loose(files->loose, oid) ? 0 : -1;
427 + ret = quick_has_loose(loose, oid) ? 0 : -1;
428 goto out;
429 }
430
@@ -532,7 +531,7 @@ out:
531 if (oi->typep == &type_scratch)
532 oi->typep = NULL;
533 if (oi->delta_base_oid)
535 - oidclr(oi->delta_base_oid, source->odb->repo->hash_algo);
534 + oidclr(oi->delta_base_oid, loose->base.odb->repo->hash_algo);
535 if (!ret)
536 oi->whence = OI_LOOSE;
537 }
@@ -540,26 +539,6 @@ out:
539 return ret;
540 }
541
543 -int odb_source_loose_read_object_info(struct odb_source *source,
544 - const struct object_id *oid,
545 - struct object_info *oi,
546 - enum object_info_flags flags)
547 -{
548 - static struct strbuf buf = STRBUF_INIT;
549 -
550 - /*
551 - * The second read shouldn't cause new loose objects to show up, unless
552 - * there was a race condition with a secondary process. We don't care
553 - * about this case though, so we simply skip reading loose objects a
554 - * second time.
555 - */
556 - if (flags & OBJECT_INFO_SECOND_READ)
557 - return -1;
558 -
559 - odb_loose_path(source, &buf, oid);
560 - return read_object_info_from_path(source, buf.buf, oid, oi, flags);
561 -}
562 -
542 static void hash_object_body(const struct git_hash_algo *algo, struct git_hash_ctx *c,
543 const void *buf, unsigned long len,
544 struct object_id *oid,
@@ -1833,7 +1812,7 @@ int for_each_loose_file_in_source(struct odb_source *source,
1812 }
1813
1814 struct for_each_object_wrapper_data {
1836 - struct odb_source *source;
1815 + struct odb_source_loose *loose;
1816 const struct object_info *request;
1817 odb_for_each_object_cb cb;
1818 void *cb_data;
@@ -1848,7 +1827,7 @@ static int for_each_object_wrapper_cb(const struct object_id *oid,
1827 if (data->request) {
1828 struct object_info oi = *data->request;
1829
1851 - if (read_object_info_from_path(data->source, path, oid, &oi, 0) < 0)
1830 + if (read_object_info_from_path(data->loose, path, oid, &oi, 0) < 0)
1831 return -1;
1832
1833 return data->cb(oid, &oi, data->cb_data);
@@ -1865,8 +1844,8 @@ static int for_each_prefixed_object_wrapper_cb(const struct object_id *oid,
1844 if (data->request) {
1845 struct object_info oi = *data->request;
1846
1868 - if (odb_source_loose_read_object_info(data->source,
1869 - oid, &oi, 0) < 0)
1847 + if (odb_source_read_object_info(&data->loose->base,
1848 + oid, &oi, 0) < 0)
1849 return -1;
1850
1851 return data->cb(oid, &oi, data->cb_data);
@@ -1881,8 +1860,9 @@ int odb_source_loose_for_each_object(struct odb_source *source,
1860 void *cb_data,
1861 const struct odb_for_each_object_options *opts)
1862 {
1863 + struct odb_source_files *files = odb_source_files_downcast(source);
1864 struct for_each_object_wrapper_data data = {
1885 - .source = source,
1865 + .loose = files->loose,
1866 .request = request,
1867 .cb = cb,
1868 .cb_data = cb_data,
object-file.h
+6 -5
@@ -21,11 +21,6 @@ struct object_info;
21 struct odb_read_stream;
22 struct odb_source;
23
24 -int odb_source_loose_read_object_info(struct odb_source *source,
25 - const struct object_id *oid,
26 - struct object_info *oi,
27 - enum object_info_flags flags);
28 -
24 int odb_source_loose_read_object_stream(struct odb_read_stream **out,
25 struct odb_source *source,
26 const struct object_id *oid);
@@ -198,6 +193,12 @@ int read_loose_object(struct repository *repo,
193 void **contents,
194 struct object_info *oi);
195
196 +int read_object_info_from_path(struct odb_source_loose *loose,
197 + const char *path,
198 + const struct object_id *oid,
199 + struct object_info *oi,
200 + enum object_info_flags flags);
201 +
202 struct odb_transaction;
203
204 /*
odb/source-files.c
+1 -1
@@ -55,7 +55,7 @@ static int odb_source_files_read_object_info(struct odb_source *source,
55 struct odb_source_files *files = odb_source_files_downcast(source);
56
57 if (!packfile_store_read_object_info(files->packed, oid, oi, flags) ||
58 - !odb_source_loose_read_object_info(source, oid, oi, flags))
58 + !odb_source_read_object_info(&files->loose->base, oid, oi, flags))
59 return 0;
60
61 return -1;
odb/source-loose.c
+24
@@ -2,10 +2,33 @@
2 #include "abspath.h"
3 #include "chdir-notify.h"
4 #include "loose.h"
5 +#include "object-file.h"
6 #include "odb.h"
7 #include "odb/source-files.h"
8 #include "odb/source-loose.h"
9 #include "oidtree.h"
10 +#include "strbuf.h"
11 +
12 +static int odb_source_loose_read_object_info(struct odb_source *source,
13 + const struct object_id *oid,
14 + struct object_info *oi,
15 + enum object_info_flags flags)
16 +{
17 + struct odb_source_loose *loose = odb_source_loose_downcast(source);
18 + static struct strbuf buf = STRBUF_INIT;
19 +
20 + /*
21 + * The second read shouldn't cause new loose objects to show up, unless
22 + * there was a race condition with a secondary process. We don't care
23 + * about this case though, so we simply skip reading loose objects a
24 + * second time.
25 + */
26 + if (flags & OBJECT_INFO_SECOND_READ)
27 + return -1;
28 +
29 + odb_loose_path(source, &buf, oid);
30 + return read_object_info_from_path(loose, buf.buf, oid, oi, flags);
31 +}
32
33 static void odb_source_loose_clear_cache(struct odb_source_loose *loose)
34 {
@@ -60,6 +83,7 @@ struct odb_source_loose *odb_source_loose_new(struct odb_source_files *files)
83 loose->base.free = odb_source_loose_free;
84 loose->base.close = odb_source_loose_close;
85 loose->base.reprepare = odb_source_loose_reprepare;
86 + loose->base.read_object_info = odb_source_loose_read_object_info;
87
88 if (!is_absolute_path(loose->base.path))
89 chdir_notify_register(NULL, odb_source_loose_reparent, loose);