odb: lift object existence check out of the "loose" backend

Before writing a new loose object we first check whether the object already exists in any of the sources attached to the object database. This results in a couple of issues: - We have a layering violation, where the source needs to be aware of objects stored in any of the other sources. - Every backend would have to reimplement this check, which feels somewhat pointless. - It is not possible to easily write an object into a source in case the same object already exists in another source. Refactor the code and lift up the object existence check from the "loose" backend into the generic ODB layer. No callers need adjustment as none of them write via a specific source, but via the ODB layer. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jul 17, 2026 at 11:32 UTC b688086b8fd56e1bbab36e6bb26e12844e6e6965
2 files changed +9 -6
odb.c
+7
@@ -997,6 +997,13 @@ int odb_write_object_ext(struct object_database *odb,
997
998 hash_object_file(odb->repo->hash_algo, buf, len, type, oid);
999
1000 + /*
1001 + * We can skip the write in case we already have the object available.
1002 + * In that case, we only freshen its mtime.
1003 + */
1004 + if (odb_freshen_object(odb, oid))
1005 + return 0;
1006 +
1007 if (compat) {
1008 const struct git_hash_algo *algo = odb->repo->hash_algo;
1009
odb/source-loose.c
+2 -6
@@ -595,16 +595,12 @@ static int odb_source_loose_write_object(struct odb_source *source,
595
596 hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
597
598 - /*
599 - * Normally if we have it in the pack then we do not bother writing
600 - * it out into .git/objects/??/?{38} file.
601 - */
602 - if (odb_freshen_object(source->odb, oid))
603 - return 0;
598 if (write_loose_object(loose, oid, hdr, hdrlen, buf, len, 0, flags))
599 return -1;
600 +
601 if (compat_oid)
602 return repo_add_loose_object_map(loose, oid, compat_oid);
603 +
604 return 0;
605 }
606