odb: store locality in object database sources

Object database sources are classified either as: - Local, which means that the source is the repository's primary source. This is typically ".git/objects". - Non-local, which is everything else. Most importantly this includes alternates and quarantine directories. This locality is often computed ad-hoc by checking whether a given object source is the first one. This works, but it is quite roundabout. Refactor the code so that we store locality when creating the sources in the first place. This makes it both more accessible and robust. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Aug 11, 2025 at 15:46 UTC 595bef7180b57889a4dec4b675a7fc6084c863ac
6 files changed +18 -8
midx.c
+3 -2
@@ -723,7 +723,7 @@ int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id)
723 return 0;
724 }
725
726 -int prepare_multi_pack_index_one(struct odb_source *source, int local)
726 +int prepare_multi_pack_index_one(struct odb_source *source)
727 {
728 struct repository *r = source->odb->repo;
729
@@ -734,7 +734,8 @@ int prepare_multi_pack_index_one(struct odb_source *source, int local)
734 if (source->midx)
735 return 1;
736
737 - source->midx = load_multi_pack_index(r, source->path, local);
737 + source->midx = load_multi_pack_index(r, source->path,
738 + source->local);
739
740 return !!source->midx;
741 }
midx.h
+1 -1
@@ -122,7 +122,7 @@ int fill_midx_entry(struct repository *r, const struct object_id *oid, struct pa
122 int midx_contains_pack(struct multi_pack_index *m,
123 const char *idx_or_pack_name);
124 int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id);
125 -int prepare_multi_pack_index_one(struct odb_source *source, int local);
125 +int prepare_multi_pack_index_one(struct odb_source *source);
126
127 /*
128 * Variant of write_midx_file which writes a MIDX containing only the packs
odb.c
+1
@@ -176,6 +176,7 @@ static int link_alt_odb_entry(struct object_database *odb,
176
177 CALLOC_ARRAY(alternate, 1);
178 alternate->odb = odb;
179 + alternate->local = false;
180 /* pathbuf.buf is already in r->objects->source_by_path */
181 alternate->path = strbuf_detach(&pathbuf, NULL);
182
odb.h
+8
@@ -63,6 +63,14 @@ struct odb_source {
63 */
64 struct multi_pack_index *midx;
65
66 + /*
67 + * Figure out whether this is the local source of the owning
68 + * repository, which would typically be its ".git/objects" directory.
69 + * This local object directory is usually where objects would be
70 + * written to.
71 + */
72 + bool local;
73 +
74 /*
75 * This is a temporary object store created by the tmp_objdir
76 * facility. Disable ref updates since the objects in the store
packfile.c
+4 -5
@@ -935,14 +935,14 @@ static void prepare_pack(const char *full_name, size_t full_name_len,
935 report_garbage(PACKDIR_FILE_GARBAGE, full_name);
936 }
937
938 -static void prepare_packed_git_one(struct odb_source *source, int local)
938 +static void prepare_packed_git_one(struct odb_source *source)
939 {
940 struct string_list garbage = STRING_LIST_INIT_DUP;
941 struct prepare_pack_data data = {
942 .m = source->midx,
943 .r = source->odb->repo,
944 .garbage = &garbage,
945 - .local = local,
945 + .local = source->local,
946 };
947
948 for_each_file_in_pack_dir(source->path, prepare_pack, &data);
@@ -1037,9 +1037,8 @@ static void prepare_packed_git(struct repository *r)
1037
1038 odb_prepare_alternates(r->objects);
1039 for (source = r->objects->sources; source; source = source->next) {
1040 - int local = (source == r->objects->sources);
1041 - prepare_multi_pack_index_one(source, local);
1042 - prepare_packed_git_one(source, local);
1040 + prepare_multi_pack_index_one(source);
1041 + prepare_packed_git_one(source);
1042 }
1043 rearrange_packed_git(r);
1044
repository.c
+1
@@ -168,6 +168,7 @@ void repo_set_gitdir(struct repository *repo,
168 if (!repo->objects->sources) {
169 CALLOC_ARRAY(repo->objects->sources, 1);
170 repo->objects->sources->odb = repo->objects;
171 + repo->objects->sources->local = true;
172 repo->objects->sources_tail = &repo->objects->sources->next;
173 }
174 expand_base_dir(&repo->objects->sources->path, o->object_dir,