odb/source: make `read_alternates()` function pluggable
Introduce a new callback function in `struct odb_source` to make the function pluggable. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Mar 5, 2026 at 15:19 UTC
7ae23630c3ed012180edc88f0a9615a0d570a77c
4 files changed
+59
-22
odb.c
+4
-22
@@ -131,10 +131,10 @@ out:
131
return usable;
132
}
133
134
-static void parse_alternates(const char *string,
135
- int sep,
136
- const char *relative_base,
137
- struct strvec *out)
134
+void parse_alternates(const char *string,
135
+ int sep,
136
+ const char *relative_base,
137
+ struct strvec *out)
138
{
139
struct strbuf pathbuf = STRBUF_INIT;
140
struct strbuf buf = STRBUF_INIT;
@@ -198,24 +198,6 @@ static void parse_alternates(const char *string,
198
strbuf_release(&buf);
199
}
200
201
-static void odb_source_read_alternates(struct odb_source *source,
202
- struct strvec *out)
203
-{
204
- struct strbuf buf = STRBUF_INIT;
205
- char *path;
206
-
207
- path = xstrfmt("%s/info/alternates", source->path);
208
- if (strbuf_read_file(&buf, path, 1024) < 0) {
209
- warn_on_fopen_errors(path);
210
- free(path);
211
- return;
212
- }
213
- parse_alternates(buf.buf, '\n', source->path, out);
214
-
215
- strbuf_release(&buf);
216
- free(path);
217
-}
218
-
201
static struct odb_source *odb_add_alternate_recursively(struct object_database *odb,
202
const char *source,
203
int depth)
odb.h
+5
@@ -500,4 +500,9 @@ int odb_write_object_stream(struct object_database *odb,
500
struct odb_write_stream *stream, size_t len,
501
struct object_id *oid);
502
503
+void parse_alternates(const char *string,
504
+ int sep,
505
+ const char *relative_base,
506
+ struct strvec *out);
507
+
508
#endif /* ODB_H */
odb/source-files.c
+22
@@ -2,9 +2,11 @@
2
#include "abspath.h"
3
#include "chdir-notify.h"
4
#include "object-file.h"
5
+#include "odb.h"
6
#include "odb/source.h"
7
#include "odb/source-files.h"
8
#include "packfile.h"
9
+#include "strbuf.h"
10
11
static void odb_source_files_reparent(const char *name UNUSED,
12
const char *old_cwd,
@@ -117,6 +119,25 @@ static int odb_source_files_write_object_stream(struct odb_source *source,
119
return odb_source_loose_write_stream(source, stream, len, oid);
120
}
121
122
+static int odb_source_files_read_alternates(struct odb_source *source,
123
+ struct strvec *out)
124
+{
125
+ struct strbuf buf = STRBUF_INIT;
126
+ char *path;
127
+
128
+ path = xstrfmt("%s/info/alternates", source->path);
129
+ if (strbuf_read_file(&buf, path, 1024) < 0) {
130
+ warn_on_fopen_errors(path);
131
+ free(path);
132
+ return 0;
133
+ }
134
+ parse_alternates(buf.buf, '\n', source->path, out);
135
+
136
+ strbuf_release(&buf);
137
+ free(path);
138
+ return 0;
139
+}
140
+
141
struct odb_source_files *odb_source_files_new(struct object_database *odb,
142
const char *path,
143
bool local)
@@ -137,6 +158,7 @@ struct odb_source_files *odb_source_files_new(struct object_database *odb,
158
files->base.freshen_object = odb_source_files_freshen_object;
159
files->base.write_object = odb_source_files_write_object;
160
files->base.write_object_stream = odb_source_files_write_object_stream;
161
+ files->base.read_alternates = odb_source_files_read_alternates;
162
163
/*
164
* Ideally, we would only ever store absolute paths in the source. This
odb/source.h
+28
@@ -54,6 +54,7 @@ struct object_id;
54
struct object_info;
55
struct odb_read_stream;
56
struct odb_write_stream;
57
+struct strvec;
58
59
/*
60
* A callback function that can be used to iterate through objects. If given,
@@ -231,6 +232,19 @@ struct odb_source {
232
int (*write_object_stream)(struct odb_source *source,
233
struct odb_write_stream *stream, size_t len,
234
struct object_id *oid);
235
+
236
+ /*
237
+ * This callback is expected to read the list of alternate object
238
+ * database sources connected to it and write them into the `strvec`.
239
+ *
240
+ * The result is expected to be paths to the alternates. All paths must
241
+ * be resolved to absolute paths.
242
+ *
243
+ * The callback is expected to return 0 on success, a negative error
244
+ * code otherwise.
245
+ */
246
+ int (*read_alternates)(struct odb_source *source,
247
+ struct strvec *out);
248
};
249
250
/*
@@ -384,4 +398,18 @@ static inline int odb_source_write_object_stream(struct odb_source *source,
398
return source->write_object_stream(source, stream, len, oid);
399
}
400
401
+/*
402
+ * Read the list of alternative object database sources from the given backend
403
+ * and populate the `strvec` with them. The listing is not recursive -- that
404
+ * is, if any of the yielded alternate sources has alternates itself, those
405
+ * will not be yielded as part of this function call.
406
+ *
407
+ * Return 0 on success, a negative error code otherwise.
408
+ */
409
+static inline int odb_source_read_alternates(struct odb_source *source,
410
+ struct strvec *out)
411
+{
412
+ return source->read_alternates(source, out);
413
+}
414
+
415
#endif