]> git.ipfire.org Git - thirdparty/git.git/commitdiff
odb: compute object hash in `odb_write_object_ext()`
authorPatrick Steinhardt <ps@pks.im>
Fri, 17 Jul 2026 09:32:11 +0000 (11:32 +0200)
committerJunio C Hamano <gitster@pobox.com>
Sun, 19 Jul 2026 02:03:48 +0000 (19:03 -0700)
Same as in a preceding commit, compute the object hash in
`odb_write_object_ext()` so that we can unify this logic.

Besides unification, this change also allows us to lift the object
existence check out of the "loose" backend into the generic layer, which
will happen in the next commit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file.c
object-file.h
odb.c
odb/source-files.c
odb/source-inmemory.c
odb/source-loose.c
odb/source-packed.c
odb/source.h
t/unit-tests/u-odb-inmemory.c

index 5283292f1ea02d1e239639526156e9413bd24e60..9ca14f484dbd5dd4430f352ca7ca6cb8907a6c8a 100644 (file)
@@ -316,31 +316,6 @@ int parse_loose_header(const char *hdr, struct object_info *oi)
        return 0;
 }
 
-static void hash_object_body(const struct git_hash_algo *algo, struct git_hash_ctx *c,
-                            const void *buf, size_t len,
-                            struct object_id *oid,
-                            char *hdr, size_t *hdrlen)
-{
-       git_hash_init(c, algo);
-       git_hash_update(c, hdr, *hdrlen);
-       git_hash_update(c, buf, len);
-       git_hash_final_oid(oid, c);
-}
-
-void write_object_file_prepare(const struct git_hash_algo *algo,
-                              const void *buf, size_t len,
-                              enum object_type type, struct object_id *oid,
-                              char *hdr, size_t *hdrlen)
-{
-       struct git_hash_ctx c;
-
-       /* Generate the header */
-       *hdrlen = format_object_header(hdr, *hdrlen, type, len);
-
-       /* Hash (function pointers) computation */
-       hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen);
-}
-
 #define CHECK_COLLISION_DEST_VANISHED -2
 
 static int check_collision(const char *source, const char *dest)
@@ -476,10 +451,16 @@ void hash_object_file(const struct git_hash_algo *algo, const void *buf,
                      size_t len, enum object_type type,
                      struct object_id *oid)
 {
+       struct git_hash_ctx c;
        char hdr[MAX_HEADER_LEN];
-       size_t hdrlen = sizeof(hdr);
+       int hdrlen;
+
+       hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
 
-       write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
+       git_hash_init(&c, algo);
+       git_hash_update(&c, hdr, hdrlen);
+       git_hash_update(&c, buf, len);
+       git_hash_final_oid(oid, &c);
 }
 
 struct transaction_packfile {
index d04ffa6493ff1766dc569ffdb9475bf5b50fe3c0..08aafcda0df67bac77485e26be9474235fcc4ed3 100644 (file)
@@ -134,10 +134,6 @@ int finalize_object_file_flags(struct repository *repo,
 void hash_object_file(const struct git_hash_algo *algo, const void *buf,
                      size_t len, enum object_type type,
                      struct object_id *oid);
-void write_object_file_prepare(const struct git_hash_algo *algo,
-                              const void *buf, size_t len,
-                              enum object_type type, struct object_id *oid,
-                              char *hdr, size_t *hdrlen);
 int write_loose_object(struct odb_source_loose *loose,
                       const struct object_id *oid, char *hdr,
                       int hdrlen, const void *buf, unsigned long len,
diff --git a/odb.c b/odb.c
index 1d6538163b54eac10bfa1bbfa02f0ea50fb8ad6b..4adbdf8a64898258b6b8cdf475cc9f744738c743 100644 (file)
--- a/odb.c
+++ b/odb.c
@@ -995,6 +995,8 @@ int odb_write_object_ext(struct object_database *odb,
        const struct git_hash_algo *compat = odb->repo->compat_hash_algo;
        struct object_id compat_oid, *compat_oid_p = NULL;
 
+       hash_object_file(odb->repo->hash_algo, buf, len, type, oid);
+
        if (compat) {
                const struct git_hash_algo *algo = odb->repo->hash_algo;
 
index 3d9f5eca327948dc31e9fca2d2376f71def889d5..06dfc8dd78aecb3a9583c59a6437f9bd3a731085 100644 (file)
@@ -162,7 +162,7 @@ static int odb_source_files_freshen_object(struct odb_source *source,
 static int odb_source_files_write_object(struct odb_source *source,
                                         const void *buf, size_t len,
                                         enum object_type type,
-                                        struct object_id *oid,
+                                        const struct object_id *oid,
                                         const struct object_id *compat_oid,
                                         enum odb_write_object_flags flags)
 {
index e727aba427a17d8dc41214659bfdb1dc461771d9..963d5203178d97f8203a4e41ce72869bdf1015f1 100644 (file)
@@ -230,15 +230,13 @@ static int odb_source_inmemory_count_objects(struct odb_source *source,
 static int odb_source_inmemory_write_object(struct odb_source *source,
                                            const void *buf, size_t len,
                                            enum object_type type,
-                                           struct object_id *oid,
+                                           const struct object_id *oid,
                                            const struct object_id *compat_oid UNUSED,
                                            enum odb_write_object_flags flags UNUSED)
 {
        struct odb_source_inmemory *inmemory = odb_source_inmemory_downcast(source);
        struct inmemory_object *object;
 
-       hash_object_file(source->odb->repo->hash_algo, buf, len, type, oid);
-
        if (!inmemory->objects) {
                CALLOC_ARRAY(inmemory->objects, 1);
                oidtree_init(inmemory->objects);
@@ -285,6 +283,8 @@ static int odb_source_inmemory_write_object_stream(struct odb_source *source,
                goto out;
        }
 
+       hash_object_file(source->odb->repo->hash_algo, data, total_read, OBJ_BLOB, oid);
+
        ret = odb_source_inmemory_write_object(source, data, len, OBJ_BLOB, oid,
                                               NULL, 0);
        if (ret < 0)
index ca223109cd46e434abae5e6acbe060956a735be8..d4715da6d1c55e87dc9ab6127c59fc4b7689153c 100644 (file)
@@ -584,19 +584,21 @@ static int odb_source_loose_freshen_object(struct odb_source *source,
 
 static int odb_source_loose_write_object(struct odb_source *source,
                                         const void *buf, size_t len,
-                                        enum object_type type, struct object_id *oid,
+                                        enum object_type type,
+                                        const struct object_id *oid,
                                         const struct object_id *compat_oid,
                                         enum odb_write_object_flags flags)
 {
        struct odb_source_loose *loose = odb_source_loose_downcast(source);
-       const struct git_hash_algo *algo = source->odb->repo->hash_algo;
        char hdr[MAX_HEADER_LEN];
-       size_t hdrlen = sizeof(hdr);
+       int hdrlen;
+
+       hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
 
-       /* Normally if we have it in the pack then we do not bother writing
+       /*
+        * Normally if we have it in the pack then we do not bother writing
         * it out into .git/objects/??/?{38} file.
         */
-       write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
        if (odb_freshen_object(source->odb, oid))
                return 0;
        if (write_loose_object(loose, oid, hdr, hdrlen, buf, len, 0, flags))
index af0d533375176fefd8bedf7102bf703b94b2b770..f7f17064472f073eee95e6369ae4a418d8250d80 100644 (file)
@@ -529,7 +529,7 @@ static int odb_source_packed_write_object(struct odb_source *source UNUSED,
                                          const void *buf UNUSED,
                                          size_t len UNUSED,
                                          enum object_type type UNUSED,
-                                         struct object_id *oid UNUSED,
+                                         const struct object_id *oid UNUSED,
                                          const struct object_id *compat_oid UNUSED,
                                          unsigned flags UNUSED)
 {
index b3c1ca3a6604fc2a3e58cad81ea18a8e377c37a4..c4e94c9d0d4615d0c8589e53cc19cae1faa86961 100644 (file)
@@ -206,7 +206,7 @@ struct odb_source {
        int (*write_object)(struct odb_source *source,
                            const void *buf, size_t len,
                            enum object_type type,
-                           struct object_id *oid,
+                           const struct object_id *oid,
                            const struct object_id *compat_oid,
                            enum odb_write_object_flags flags);
 
@@ -416,7 +416,7 @@ static inline int odb_source_freshen_object(struct odb_source *source,
 static inline int odb_source_write_object(struct odb_source *source,
                                          const void *buf, unsigned long len,
                                          enum object_type type,
-                                         struct object_id *oid,
+                                         const struct object_id *oid,
                                          const struct object_id *compat_oid,
                                          enum odb_write_object_flags flags)
 {
index 2dbc3ab1df689a9035afa03230fbf6162306a940..28a69fc24477c43062841f91cbf760a5c0e14433 100644 (file)
@@ -43,6 +43,7 @@ static void cl_assert_write_object(struct odb_source_inmemory *source,
                                   struct object_id *oid)
 {
        size_t content_len = strlen(content);
+       hash_object_file(repo.hash_algo, content, content_len, type, oid);
        cl_must_pass(odb_source_write_object(&source->base, content, content_len,
                                             type, oid, NULL, 0));
 }