odb: get rid of `the_repository` when handling alternates
The functions to manage alternates all depend on `the_repository`. Refactor them to accept an object database as a parameter and adjust all callers. The functions are renamed accordingly. Note that right now the situation is still somewhat weird because we end up using the object store path provided by the object store's repository anyway. Consequently, we could have instead passed in a pointer to the repository instead of passing in the pointer to the object store. This will be addressed in subsequent commits though, where we will start to use the path owned by the object store itself. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Jul 1, 2025 at 14:22 UTC
c44185f6c10fb2d306efe505112982a7c3b93789
14 files changed
+83
-64
builtin/clone.c
+6
-4
@@ -171,7 +171,7 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)
171
} else {
172
struct strbuf sb = STRBUF_INIT;
173
strbuf_addf(&sb, "%s/objects", ref_git);
174
- add_to_alternates_file(sb.buf);
174
+ odb_add_to_alternates_file(the_repository->objects, sb.buf);
175
strbuf_release(&sb);
176
}
177
@@ -212,12 +212,14 @@ static void copy_alternates(struct strbuf *src, const char *src_repo)
212
if (!line.len || line.buf[0] == '#')
213
continue;
214
if (is_absolute_path(line.buf)) {
215
- add_to_alternates_file(line.buf);
215
+ odb_add_to_alternates_file(the_repository->objects,
216
+ line.buf);
217
continue;
218
}
219
abs_path = mkpathdup("%s/objects/%s", src_repo, line.buf);
220
if (!normalize_path_copy(abs_path, abs_path))
220
- add_to_alternates_file(abs_path);
221
+ odb_add_to_alternates_file(the_repository->objects,
222
+ abs_path);
223
else
224
warning("skipping invalid relative alternate: %s/%s",
225
src_repo, line.buf);
@@ -352,7 +354,7 @@ static void clone_local(const char *src_repo, const char *dest_repo)
354
struct strbuf alt = STRBUF_INIT;
355
get_common_dir(&alt, src_repo);
356
strbuf_addstr(&alt, "/objects");
355
- add_to_alternates_file(alt.buf);
357
+ odb_add_to_alternates_file(the_repository->objects, alt.buf);
358
strbuf_release(&alt);
359
} else {
360
struct strbuf src = STRBUF_INIT;
builtin/fsck.c
+3
-3
@@ -997,7 +997,7 @@ int cmd_fsck(int argc,
997
for_each_packed_object(the_repository,
998
mark_packed_for_connectivity, NULL, 0);
999
} else {
1000
- prepare_alt_odb(the_repository);
1000
+ odb_prepare_alternates(the_repository->objects);
1001
for (source = the_repository->objects->sources; source; source = source->next)
1002
fsck_object_dir(source->path);
1003
@@ -1108,7 +1108,7 @@ int cmd_fsck(int argc,
1108
if (the_repository->settings.core_commit_graph) {
1109
struct child_process commit_graph_verify = CHILD_PROCESS_INIT;
1110
1111
- prepare_alt_odb(the_repository);
1111
+ odb_prepare_alternates(the_repository->objects);
1112
for (source = the_repository->objects->sources; source; source = source->next) {
1113
child_process_init(&commit_graph_verify);
1114
commit_graph_verify.git_cmd = 1;
@@ -1126,7 +1126,7 @@ int cmd_fsck(int argc,
1126
if (the_repository->settings.core_multi_pack_index) {
1127
struct child_process midx_verify = CHILD_PROCESS_INIT;
1128
1129
- prepare_alt_odb(the_repository);
1129
+ odb_prepare_alternates(the_repository->objects);
1130
for (source = the_repository->objects->sources; source; source = source->next) {
1131
child_process_init(&midx_verify);
1132
midx_verify.git_cmd = 1;
builtin/grep.c
+1
-1
@@ -462,7 +462,7 @@ static int grep_submodule(struct grep_opt *opt,
462
463
/*
464
* NEEDSWORK: repo_read_gitmodules() might call
465
- * add_to_alternates_memory() via config_from_gitmodules(). This
465
+ * odb_add_to_alternates_memory() via config_from_gitmodules(). This
466
* operation causes a race condition with concurrent object readings
467
* performed by the worker threads. That's why we need obj_read_lock()
468
* here. It should be removed once it's no longer necessary to add the
builtin/repack.c
+2
-1
@@ -1256,7 +1256,8 @@ int cmd_repack(int argc,
1256
if (write_bitmaps && !(pack_everything & ALL_INTO_ONE) && !write_midx)
1257
die(_(incremental_bitmap_conflict_error));
1258
1259
- if (write_bitmaps && po_args.local && has_alt_odb(the_repository)) {
1259
+ if (write_bitmaps && po_args.local &&
1260
+ odb_has_alternates(the_repository->objects)) {
1261
/*
1262
* When asked to do a local repack, but we have
1263
* packfiles that are inherited from an alternate, then
commit-graph.c
+2
-2
@@ -649,7 +649,7 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
649
count = st->st_size / (the_hash_algo->hexsz + 1);
650
CALLOC_ARRAY(oids, count);
651
652
- prepare_alt_odb(r);
652
+ odb_prepare_alternates(r->objects);
653
654
for (i = 0; i < count; i++) {
655
struct odb_source *source;
@@ -778,7 +778,7 @@ static int prepare_commit_graph(struct repository *r)
778
if (!commit_graph_compatible(r))
779
return 0;
780
781
- prepare_alt_odb(r);
781
+ odb_prepare_alternates(r->objects);
782
for (source = r->objects->sources;
783
!r->objects->commit_graph && source;
784
source = source->next)
loose.c
+1
-1
@@ -112,7 +112,7 @@ int repo_read_loose_object_map(struct repository *repo)
112
if (!should_use_loose_object_map(repo))
113
return 0;
114
115
- prepare_alt_odb(repo);
115
+ odb_prepare_alternates(repo->objects);
116
117
for (source = repo->objects->sources; source; source = source->next) {
118
if (load_one_loose_object_map(repo, source) < 0) {
object-file.c
+5
-5
@@ -106,7 +106,7 @@ static int check_and_freshen_nonlocal(const struct object_id *oid, int freshen)
106
{
107
struct odb_source *source;
108
109
- prepare_alt_odb(the_repository);
109
+ odb_prepare_alternates(the_repository->objects);
110
for (source = the_repository->objects->sources->next; source; source = source->next) {
111
if (check_and_freshen_odb(source, oid, freshen))
112
return 1;
@@ -205,7 +205,7 @@ static int stat_loose_object(struct repository *r, const struct object_id *oid,
205
struct odb_source *source;
206
static struct strbuf buf = STRBUF_INIT;
207
208
- prepare_alt_odb(r);
208
+ odb_prepare_alternates(r->objects);
209
for (source = r->objects->sources; source; source = source->next) {
210
*path = odb_loose_path(source, &buf, oid);
211
if (!lstat(*path, st))
@@ -227,7 +227,7 @@ static int open_loose_object(struct repository *r,
227
int most_interesting_errno = ENOENT;
228
static struct strbuf buf = STRBUF_INIT;
229
230
- prepare_alt_odb(r);
230
+ odb_prepare_alternates(r->objects);
231
for (source = r->objects->sources; source; source = source->next) {
232
*path = odb_loose_path(source, &buf, oid);
233
fd = git_open(*path);
@@ -246,7 +246,7 @@ static int quick_has_loose(struct repository *r,
246
{
247
struct odb_source *source;
248
249
- prepare_alt_odb(r);
249
+ odb_prepare_alternates(r->objects);
250
for (source = r->objects->sources; source; source = source->next) {
251
if (oidtree_contains(odb_loose_cache(source, oid), oid))
252
return 1;
@@ -1439,7 +1439,7 @@ int for_each_loose_object(each_loose_object_fn cb, void *data,
1439
{
1440
struct odb_source *source;
1441
1442
- prepare_alt_odb(the_repository);
1442
+ odb_prepare_alternates(the_repository->objects);
1443
for (source = the_repository->objects->sources; source; source = source->next) {
1444
int r = for_each_loose_file_in_objdir(source->path, cb, NULL,
1445
NULL, data);
object-name.c
+1
-1
@@ -376,7 +376,7 @@ static int init_object_disambiguation(struct repository *r,
376
ds->hex_pfx[len] = '\0';
377
ds->repo = r;
378
ds->bin_pfx.algo = algo ? hash_algo_by_ptr(algo) : GIT_HASH_UNKNOWN;
379
- prepare_alt_odb(r);
379
+ odb_prepare_alternates(r->objects);
380
return 0;
381
}
382
odb.c
+20
-24
@@ -272,10 +272,11 @@ static void read_info_alternates(struct object_database *odb,
272
free(path);
273
}
274
275
-void add_to_alternates_file(const char *reference)
275
+void odb_add_to_alternates_file(struct object_database *odb,
276
+ const char *reference)
277
{
278
struct lock_file lock = LOCK_INIT;
278
- char *alts = repo_git_path(the_repository, "objects/info/alternates");
279
+ char *alts = repo_git_path(odb->repo, "objects/info/alternates");
280
FILE *in, *out;
281
int found = 0;
282
@@ -308,22 +309,23 @@ void add_to_alternates_file(const char *reference)
309
fprintf_or_die(out, "%s\n", reference);
310
if (commit_lock_file(&lock))
311
die_errno(_("unable to move new alternates file into place"));
311
- if (the_repository->objects->loaded_alternates)
312
- link_alt_odb_entries(the_repository->objects, reference,
312
+ if (odb->loaded_alternates)
313
+ link_alt_odb_entries(odb, reference,
314
'\n', NULL, 0);
315
}
316
free(alts);
317
}
318
318
-void add_to_alternates_memory(const char *reference)
319
+void odb_add_to_alternates_memory(struct object_database *odb,
320
+ const char *reference)
321
{
322
/*
323
* Make sure alternates are initialized, or else our entry may be
324
* overwritten when they are.
325
*/
324
- prepare_alt_odb(the_repository);
326
+ odb_prepare_alternates(odb);
327
326
- link_alt_odb_entries(the_repository->objects, reference,
328
+ link_alt_odb_entries(odb, reference,
329
'\n', NULL, 0);
330
}
331
@@ -335,7 +337,7 @@ struct odb_source *set_temporary_primary_odb(const char *dir, int will_destroy)
337
* Make sure alternates are initialized, or else our entry may be
338
* overwritten when they are.
339
*/
338
- prepare_alt_odb(the_repository);
340
+ odb_prepare_alternates(the_repository->objects);
341
342
/*
343
* Make a new primary odb and link the old primary ODB in as an
@@ -379,12 +381,6 @@ void restore_primary_odb(struct odb_source *restore_alt, const char *old_path)
381
free_object_directory(cur_alt);
382
}
383
382
-/*
383
- * Compute the exact path an alternate is at and returns it. In case of
384
- * error NULL is returned and the human readable error is added to `err`
385
- * `path` may be relative and should point to $GIT_DIR.
386
- * `err` must not be null.
387
- */
384
char *compute_alternate_path(const char *path, struct strbuf *err)
385
{
386
char *ref_git = NULL;
@@ -455,7 +451,7 @@ struct odb_source *odb_find_source(struct object_database *odb, const char *obj_
451
char *obj_dir_real = real_pathdup(obj_dir, 1);
452
struct strbuf odb_path_real = STRBUF_INIT;
453
458
- prepare_alt_odb(odb->repo);
454
+ odb_prepare_alternates(odb);
455
for (source = odb->sources; source; source = source->next) {
456
strbuf_realpath(&odb_path_real, source->path, 1);
457
if (!strcmp(obj_dir_real, odb_path_real.buf))
@@ -573,7 +569,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
569
struct odb_source *alternate;
570
int r = 0;
571
576
- prepare_alt_odb(the_repository);
572
+ odb_prepare_alternates(the_repository->objects);
573
for (alternate = the_repository->objects->sources->next; alternate; alternate = alternate->next) {
574
r = fn(alternate, cb);
575
if (r)
@@ -582,21 +578,21 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
578
return r;
579
}
580
585
-void prepare_alt_odb(struct repository *r)
581
+void odb_prepare_alternates(struct object_database *odb)
582
{
587
- if (r->objects->loaded_alternates)
583
+ if (odb->loaded_alternates)
584
return;
585
590
- link_alt_odb_entries(r->objects, r->objects->alternate_db, PATH_SEP, NULL, 0);
586
+ link_alt_odb_entries(odb, odb->alternate_db, PATH_SEP, NULL, 0);
587
592
- read_info_alternates(r->objects, r->objects->sources->path, 0);
593
- r->objects->loaded_alternates = 1;
588
+ read_info_alternates(odb, odb->sources->path, 0);
589
+ odb->loaded_alternates = 1;
590
}
591
596
-int has_alt_odb(struct repository *r)
592
+int odb_has_alternates(struct object_database *odb)
593
{
598
- prepare_alt_odb(r);
599
- return !!r->objects->sources->next;
594
+ odb_prepare_alternates(odb);
595
+ return !!odb->sources->next;
596
}
597
598
int obj_read_use_lock = 0;
odb.h
+36
-17
@@ -13,6 +13,14 @@ struct oidtree;
13
struct strbuf;
14
struct repository;
15
16
+/*
17
+ * Compute the exact path an alternate is at and returns it. In case of
18
+ * error NULL is returned and the human readable error is added to `err`
19
+ * `path` may be relative and should point to $GIT_DIR.
20
+ * `err` must not be null.
21
+ */
22
+char *compute_alternate_path(const char *path, struct strbuf *err);
23
+
24
/*
25
* The source is the part of the object database that stores the actual
26
* objects. It thus encapsulates the logic to read and write the specific
@@ -65,27 +73,11 @@ struct odb_source {
73
char *path;
74
};
75
68
-void prepare_alt_odb(struct repository *r);
69
-int has_alt_odb(struct repository *r);
70
-char *compute_alternate_path(const char *path, struct strbuf *err);
76
typedef int alt_odb_fn(struct odb_source *, void *);
77
int foreach_alt_odb(alt_odb_fn, void*);
78
typedef void alternate_ref_fn(const struct object_id *oid, void *);
79
void for_each_alternate_ref(alternate_ref_fn, void *);
80
76
-/*
77
- * Add the directory to the on-disk alternates file; the new entry will also
78
- * take effect in the current process.
79
- */
80
-void add_to_alternates_file(const char *dir);
81
-
82
-/*
83
- * Add the directory to the in-memory list of alternates (along with any
84
- * recursive alternates it points to), but do not modify the on-disk alternates
85
- * file.
86
- */
87
-void add_to_alternates_memory(const char *dir);
88
-
81
/*
82
* Replace the current writable object directory with the specified temporary
83
* object directory; returns the former primary object directory.
@@ -124,7 +116,7 @@ struct object_database {
116
/*
117
* A list of alternate object directories loaded from the environment;
118
* this should not generally need to be accessed directly, but will
127
- * populate the "sources" list when prepare_alt_odb() is run.
119
+ * populate the "sources" list when odb_prepare_alternates() is run.
120
*/
121
char *alternate_db;
122
@@ -209,6 +201,33 @@ struct odb_source *odb_find_source(struct object_database *odb, const char *obj_
201
int odb_mkstemp(struct object_database *odb,
202
struct strbuf *temp_filename, const char *pattern);
203
204
+/*
205
+ * Prepare alternate object sources for the given database by reading
206
+ * "objects/info/alternates" and opening the respective sources.
207
+ */
208
+void odb_prepare_alternates(struct object_database *odb);
209
+
210
+/*
211
+ * Check whether the object database has any alternates. The primary object
212
+ * source does not count as alternate.
213
+ */
214
+int odb_has_alternates(struct object_database *odb);
215
+
216
+/*
217
+ * Add the directory to the on-disk alternates file; the new entry will also
218
+ * take effect in the current process.
219
+ */
220
+void odb_add_to_alternates_file(struct object_database *odb,
221
+ const char *dir);
222
+
223
+/*
224
+ * Add the directory to the in-memory list of alternate sources (along with any
225
+ * recursive alternates it points to), but do not modify the on-disk alternates
226
+ * file.
227
+ */
228
+void odb_add_to_alternates_memory(struct object_database *odb,
229
+ const char *dir);
230
+
231
void *repo_read_object_file(struct repository *r,
232
const struct object_id *oid,
233
enum object_type *type,
packfile.c
+2
-2
@@ -1034,7 +1034,7 @@ static void prepare_packed_git(struct repository *r)
1034
if (r->objects->packed_git_initialized)
1035
return;
1036
1037
- prepare_alt_odb(r);
1037
+ odb_prepare_alternates(r->objects);
1038
for (source = r->objects->sources; source; source = source->next) {
1039
int local = (source == r->objects->sources);
1040
prepare_multi_pack_index_one(r, source->path, local);
@@ -1059,7 +1059,7 @@ void reprepare_packed_git(struct repository *r)
1059
* the lifetime of the process.
1060
*/
1061
r->objects->loaded_alternates = 0;
1062
- prepare_alt_odb(r);
1062
+ odb_prepare_alternates(r->objects);
1063
1064
for (source = r->objects->sources; source; source = source->next)
1065
odb_clear_loose_cache(source);
submodule.c
+2
-1
@@ -189,7 +189,8 @@ int register_all_submodule_odb_as_alternates(void)
189
int ret = added_submodule_odb_paths.nr;
190
191
for (i = 0; i < added_submodule_odb_paths.nr; i++)
192
- add_to_alternates_memory(added_submodule_odb_paths.items[i].string);
192
+ odb_add_to_alternates_memory(the_repository->objects,
193
+ added_submodule_odb_paths.items[i].string);
194
if (ret) {
195
string_list_clear(&added_submodule_odb_paths, 0);
196
trace2_data_intmax("submodule", the_repository,
t/helper/test-ref-store.c
+1
-1
@@ -79,7 +79,7 @@ static const char **get_store(const char **argv, struct ref_store **refs)
79
if (!repo_submodule_path_append(the_repository,
80
&sb, gitdir, "objects/"))
81
die("computing submodule path failed");
82
- add_to_alternates_memory(sb.buf);
82
+ odb_add_to_alternates_memory(the_repository->objects, sb.buf);
83
strbuf_release(&sb);
84
85
*refs = repo_get_submodule_ref_store(the_repository, gitdir);
tmp-objdir.c
+1
-1
@@ -304,7 +304,7 @@ const char **tmp_objdir_env(const struct tmp_objdir *t)
304
305
void tmp_objdir_add_as_alternate(const struct tmp_objdir *t)
306
{
307
- add_to_alternates_memory(t->path.buf);
307
+ odb_add_to_alternates_memory(t->repo->objects, t->path.buf);
308
}
309
310
void tmp_objdir_replace_primary_odb(struct tmp_objdir *t, int will_destroy)