loose: write loose objects map via their source

When a repository is configured to have a compatibility hash algorithm we keep track of object ID mappings for loose objects via the loose object map. This map simply maps an object ID of the actual hash to the object ID of the compatibility hash. This loose object map is an inherent property of the loose files backend and thus of one specific object source. Refactor the interfaces to reflect this by requiring a `struct odb_source` as input instead of a repository. This prepares for subsequent commits where we will refactor writing of loose objects to work on a `struct odb_source`, as well. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jul 17, 2025 at 06:56 UTC 0f9b18935745fcdebcad613a6e3e52db5b29b1d4
3 files changed +15 -11
loose.c
+9 -7
@@ -166,7 +166,8 @@ errout:
166 return -1;
167 }
168
169 -static int write_one_object(struct repository *repo, const struct object_id *oid,
169 +static int write_one_object(struct odb_source *source,
170 + const struct object_id *oid,
171 const struct object_id *compat_oid)
172 {
173 struct lock_file lock;
@@ -174,7 +175,7 @@ static int write_one_object(struct repository *repo, const struct object_id *oid
175 struct stat st;
176 struct strbuf buf = STRBUF_INIT, path = STRBUF_INIT;
177
177 - repo_common_path_replace(repo, &path, "objects/loose-object-idx");
178 + strbuf_addf(&path, "%s/loose-object-idx", source->path);
179 hold_lock_file_for_update_timeout(&lock, path.buf, LOCK_DIE_ON_ERROR, -1);
180
181 fd = open(path.buf, O_WRONLY | O_CREAT | O_APPEND, 0666);
@@ -190,7 +191,7 @@ static int write_one_object(struct repository *repo, const struct object_id *oid
191 goto errout;
192 if (close(fd))
193 goto errout;
193 - adjust_shared_perm(repo, path.buf);
194 + adjust_shared_perm(source->odb->repo, path.buf);
195 rollback_lock_file(&lock);
196 strbuf_release(&buf);
197 strbuf_release(&path);
@@ -204,17 +205,18 @@ errout:
205 return -1;
206 }
207
207 -int repo_add_loose_object_map(struct repository *repo, const struct object_id *oid,
208 +int repo_add_loose_object_map(struct odb_source *source,
209 + const struct object_id *oid,
210 const struct object_id *compat_oid)
211 {
212 int inserted = 0;
213
212 - if (!should_use_loose_object_map(repo))
214 + if (!should_use_loose_object_map(source->odb->repo))
215 return 0;
216
215 - inserted = insert_loose_map(repo->objects->sources, oid, compat_oid);
217 + inserted = insert_loose_map(source, oid, compat_oid);
218 if (inserted)
217 - return write_one_object(repo, oid, compat_oid);
219 + return write_one_object(source, oid, compat_oid);
220 return 0;
221 }
222
loose.h
+3 -1
@@ -4,6 +4,7 @@
4 #include "khash.h"
5
6 struct repository;
7 +struct odb_source;
8
9 struct loose_object_map {
10 kh_oid_map_t *to_compat;
@@ -16,7 +17,8 @@ int repo_loose_object_map_oid(struct repository *repo,
17 const struct object_id *src,
18 const struct git_hash_algo *dest_algo,
19 struct object_id *dest);
19 -int repo_add_loose_object_map(struct repository *repo, const struct object_id *oid,
20 +int repo_add_loose_object_map(struct odb_source *source,
21 + const struct object_id *oid,
22 const struct object_id *compat_oid);
23 int repo_read_loose_object_map(struct repository *repo);
24 int repo_write_loose_object_map(struct repository *repo);
object-file.c
+3 -3
@@ -1025,7 +1025,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,
1025 err = finalize_object_file_flags(the_repository, tmp_file.buf, filename.buf,
1026 FOF_SKIP_COLLISION_CHECK);
1027 if (!err && compat)
1028 - err = repo_add_loose_object_map(the_repository, oid, &compat_oid);
1028 + err = repo_add_loose_object_map(the_repository->objects->sources, oid, &compat_oid);
1029 cleanup:
1030 strbuf_release(&tmp_file);
1031 strbuf_release(&filename);
@@ -1069,7 +1069,7 @@ int write_object_file_flags(const void *buf, unsigned long len,
1069 if (write_loose_object(oid, hdr, hdrlen, buf, len, 0, flags))
1070 return -1;
1071 if (compat)
1072 - return repo_add_loose_object_map(repo, oid, &compat_oid);
1072 + return repo_add_loose_object_map(repo->objects->sources, oid, &compat_oid);
1073 return 0;
1074 }
1075
@@ -1103,7 +1103,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
1103 hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
1104 ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime, 0);
1105 if (!ret && compat)
1106 - ret = repo_add_loose_object_map(the_repository, oid, &compat_oid);
1106 + ret = repo_add_loose_object_map(the_repository->objects->sources, oid, &compat_oid);
1107 free(buf);
1108
1109 return ret;