odb: compute object hash in `odb_write_object_ext()`
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>
Patrick Steinhardt committed
Jul 17, 2026 at 11:32 UTC
46a586a7199a78d2280ddb22368378693541fff0
9 files changed
+25
-43
object-file.c
+8
-27
@@ -316,31 +316,6 @@ int parse_loose_header(const char *hdr, struct object_info *oi)
316
return 0;
317
}
318
319
-static void hash_object_body(const struct git_hash_algo *algo, struct git_hash_ctx *c,
320
- const void *buf, size_t len,
321
- struct object_id *oid,
322
- char *hdr, size_t *hdrlen)
323
-{
324
- git_hash_init(c, algo);
325
- git_hash_update(c, hdr, *hdrlen);
326
- git_hash_update(c, buf, len);
327
- git_hash_final_oid(oid, c);
328
-}
329
-
330
-void write_object_file_prepare(const struct git_hash_algo *algo,
331
- const void *buf, size_t len,
332
- enum object_type type, struct object_id *oid,
333
- char *hdr, size_t *hdrlen)
334
-{
335
- struct git_hash_ctx c;
336
-
337
- /* Generate the header */
338
- *hdrlen = format_object_header(hdr, *hdrlen, type, len);
339
-
340
- /* Hash (function pointers) computation */
341
- hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen);
342
-}
343
-
319
#define CHECK_COLLISION_DEST_VANISHED -2
320
321
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,
451
size_t len, enum object_type type,
452
struct object_id *oid)
453
{
454
+ struct git_hash_ctx c;
455
char hdr[MAX_HEADER_LEN];
480
- size_t hdrlen = sizeof(hdr);
456
+ int hdrlen;
457
+
458
+ hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
459
482
- write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
460
+ git_hash_init(&c, algo);
461
+ git_hash_update(&c, hdr, hdrlen);
462
+ git_hash_update(&c, buf, len);
463
+ git_hash_final_oid(oid, &c);
464
}
465
466
struct transaction_packfile {
object-file.h
-4
@@ -134,10 +134,6 @@ int finalize_object_file_flags(struct repository *repo,
134
void hash_object_file(const struct git_hash_algo *algo, const void *buf,
135
size_t len, enum object_type type,
136
struct object_id *oid);
137
-void write_object_file_prepare(const struct git_hash_algo *algo,
138
- const void *buf, size_t len,
139
- enum object_type type, struct object_id *oid,
140
- char *hdr, size_t *hdrlen);
137
int write_loose_object(struct odb_source_loose *loose,
138
const struct object_id *oid, char *hdr,
139
int hdrlen, const void *buf, unsigned long len,
odb.c
+2
@@ -995,6 +995,8 @@ int odb_write_object_ext(struct object_database *odb,
995
const struct git_hash_algo *compat = odb->repo->compat_hash_algo;
996
struct object_id compat_oid, *compat_oid_p = NULL;
997
998
+ hash_object_file(odb->repo->hash_algo, buf, len, type, oid);
999
+
1000
if (compat) {
1001
const struct git_hash_algo *algo = odb->repo->hash_algo;
1002
odb/source-files.c
+1
-1
@@ -162,7 +162,7 @@ static int odb_source_files_freshen_object(struct odb_source *source,
162
static int odb_source_files_write_object(struct odb_source *source,
163
const void *buf, size_t len,
164
enum object_type type,
165
- struct object_id *oid,
165
+ const struct object_id *oid,
166
const struct object_id *compat_oid,
167
enum odb_write_object_flags flags)
168
{
odb/source-inmemory.c
+3
-3
@@ -230,15 +230,13 @@ static int odb_source_inmemory_count_objects(struct odb_source *source,
230
static int odb_source_inmemory_write_object(struct odb_source *source,
231
const void *buf, size_t len,
232
enum object_type type,
233
- struct object_id *oid,
233
+ const struct object_id *oid,
234
const struct object_id *compat_oid UNUSED,
235
enum odb_write_object_flags flags UNUSED)
236
{
237
struct odb_source_inmemory *inmemory = odb_source_inmemory_downcast(source);
238
struct inmemory_object *object;
239
240
- hash_object_file(source->odb->repo->hash_algo, buf, len, type, oid);
241
-
240
if (!inmemory->objects) {
241
CALLOC_ARRAY(inmemory->objects, 1);
242
oidtree_init(inmemory->objects);
@@ -285,6 +283,8 @@ static int odb_source_inmemory_write_object_stream(struct odb_source *source,
283
goto out;
284
}
285
286
+ hash_object_file(source->odb->repo->hash_algo, data, total_read, OBJ_BLOB, oid);
287
+
288
ret = odb_source_inmemory_write_object(source, data, len, OBJ_BLOB, oid,
289
NULL, 0);
290
if (ret < 0)
odb/source-loose.c
+7
-5
@@ -584,19 +584,21 @@ static int odb_source_loose_freshen_object(struct odb_source *source,
584
585
static int odb_source_loose_write_object(struct odb_source *source,
586
const void *buf, size_t len,
587
- enum object_type type, struct object_id *oid,
587
+ enum object_type type,
588
+ const struct object_id *oid,
589
const struct object_id *compat_oid,
590
enum odb_write_object_flags flags)
591
{
592
struct odb_source_loose *loose = odb_source_loose_downcast(source);
592
- const struct git_hash_algo *algo = source->odb->repo->hash_algo;
593
char hdr[MAX_HEADER_LEN];
594
- size_t hdrlen = sizeof(hdr);
594
+ int hdrlen;
595
+
596
+ hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
597
596
- /* Normally if we have it in the pack then we do not bother writing
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
*/
599
- write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
602
if (odb_freshen_object(source->odb, oid))
603
return 0;
604
if (write_loose_object(loose, oid, hdr, hdrlen, buf, len, 0, flags))
odb/source-packed.c
+1
-1
@@ -529,7 +529,7 @@ static int odb_source_packed_write_object(struct odb_source *source UNUSED,
529
const void *buf UNUSED,
530
size_t len UNUSED,
531
enum object_type type UNUSED,
532
- struct object_id *oid UNUSED,
532
+ const struct object_id *oid UNUSED,
533
const struct object_id *compat_oid UNUSED,
534
unsigned flags UNUSED)
535
{
odb/source.h
+2
-2
@@ -206,7 +206,7 @@ struct odb_source {
206
int (*write_object)(struct odb_source *source,
207
const void *buf, size_t len,
208
enum object_type type,
209
- struct object_id *oid,
209
+ const struct object_id *oid,
210
const struct object_id *compat_oid,
211
enum odb_write_object_flags flags);
212
@@ -416,7 +416,7 @@ static inline int odb_source_freshen_object(struct odb_source *source,
416
static inline int odb_source_write_object(struct odb_source *source,
417
const void *buf, unsigned long len,
418
enum object_type type,
419
- struct object_id *oid,
419
+ const struct object_id *oid,
420
const struct object_id *compat_oid,
421
enum odb_write_object_flags flags)
422
{
t/unit-tests/u-odb-inmemory.c
+1
@@ -43,6 +43,7 @@ static void cl_assert_write_object(struct odb_source_inmemory *source,
43
struct object_id *oid)
44
{
45
size_t content_len = strlen(content);
46
+ hash_object_file(repo.hash_algo, content, content_len, type, oid);
47
cl_must_pass(odb_source_write_object(&source->base, content, content_len,
48
type, oid, NULL, 0));
49
}