object-file: get rid of `the_repository` in `force_object_loose()`

The function `force_object_loose()` forces an object to become a loose object in case it only exists in its packed form. To do so it implicitly relies on `the_repository`. Refactor the function by passing a `struct odb_source` as parameter. While the check whether any such loose object exists already acts on the whole object database, writing the loose object happens in one specific source. 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 c2b5d1490a4b6b8b1a50b9ef82ec204811d7ccf1
3 files changed +13 -11
builtin/pack-objects.c
+2 -1
@@ -4411,7 +4411,8 @@ static void loosen_unused_packed_objects(void)
4411 if (!packlist_find(&to_pack, &oid) &&
4412 !has_sha1_pack_kept_or_nonlocal(&oid) &&
4413 !loosened_object_can_be_discarded(&oid, p->mtime)) {
4414 - if (force_object_loose(&oid, p->mtime))
4414 + if (force_object_loose(the_repository->objects->sources,
4415 + &oid, p->mtime))
4416 die(_("unable to force loose object"));
4417 loosened_objects_nr++;
4418 }
object-file.c
+9 -9
@@ -1077,10 +1077,10 @@ int write_object_file(struct odb_source *source,
1077 return 0;
1078 }
1079
1080 -int force_object_loose(const struct object_id *oid, time_t mtime)
1080 +int force_object_loose(struct odb_source *source,
1081 + const struct object_id *oid, time_t mtime)
1082 {
1082 - struct repository *repo = the_repository;
1083 - const struct git_hash_algo *compat = repo->compat_hash_algo;
1083 + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo;
1084 void *buf;
1085 unsigned long len;
1086 struct object_info oi = OBJECT_INFO_INIT;
@@ -1090,24 +1090,24 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
1090 int hdrlen;
1091 int ret;
1092
1093 - for (struct odb_source *source = repo->objects->sources; source; source = source->next)
1094 - if (has_loose_object(source, oid))
1093 + for (struct odb_source *s = source->odb->sources; s; s = s->next)
1094 + if (has_loose_object(s, oid))
1095 return 0;
1096
1097 oi.typep = &type;
1098 oi.sizep = &len;
1099 oi.contentp = &buf;
1100 - if (odb_read_object_info_extended(the_repository->objects, oid, &oi, 0))
1100 + if (odb_read_object_info_extended(source->odb, oid, &oi, 0))
1101 return error(_("cannot read object for %s"), oid_to_hex(oid));
1102 if (compat) {
1103 - if (repo_oid_to_algop(repo, oid, compat, &compat_oid))
1103 + if (repo_oid_to_algop(source->odb->repo, oid, compat, &compat_oid))
1104 return error(_("cannot map object %s to %s"),
1105 oid_to_hex(oid), compat->name);
1106 }
1107 hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
1108 - ret = write_loose_object(repo->objects->sources, oid, hdr, hdrlen, buf, len, mtime, 0);
1108 + ret = write_loose_object(source, oid, hdr, hdrlen, buf, len, mtime, 0);
1109 if (!ret && compat)
1110 - ret = repo_add_loose_object_map(the_repository->objects->sources, oid, &compat_oid);
1110 + ret = repo_add_loose_object_map(source, oid, &compat_oid);
1111 free(buf);
1112
1113 return ret;
object-file.h
+2 -1
@@ -161,7 +161,8 @@ int stream_loose_object(struct odb_source *source,
161 struct input_stream *in_stream, size_t len,
162 struct object_id *oid);
163
164 -int force_object_loose(const struct object_id *oid, time_t mtime);
164 +int force_object_loose(struct odb_source *source,
165 + const struct object_id *oid, time_t mtime);
166
167 /**
168 * With in-core object data in "buf", rehash it to make sure the