Skip to content

Commit 681b07d

Browse files
pcloudsgitster
authored andcommitted
index-pack: hash non-delta objects while reading from stream
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent aa3bb87 commit 681b07d

File tree

1 file changed

+30
-11
lines changed

1 file changed

+30
-11
lines changed

builtin/index-pack.c

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -384,30 +384,53 @@ static void unlink_base_data(struct base_data *c)
384384
free_base_data(c);
385385
}
386386

387-
static void *unpack_entry_data(unsigned long offset, unsigned long size)
387+
static int is_delta_type(enum object_type type)
388+
{
389+
return (type == OBJ_REF_DELTA || type == OBJ_OFS_DELTA);
390+
}
391+
392+
static void *unpack_entry_data(unsigned long offset, unsigned long size,
393+
enum object_type type, unsigned char *sha1)
388394
{
389395
int status;
390396
git_zstream stream;
391397
void *buf = xmalloc(size);
398+
git_SHA_CTX c;
399+
char hdr[32];
400+
int hdrlen;
401+
402+
if (!is_delta_type(type)) {
403+
hdrlen = sprintf(hdr, "%s %lu", typename(type), size) + 1;
404+
git_SHA1_Init(&c);
405+
git_SHA1_Update(&c, hdr, hdrlen);
406+
} else
407+
sha1 = NULL;
392408

393409
memset(&stream, 0, sizeof(stream));
394410
git_inflate_init(&stream);
395411
stream.next_out = buf;
396412
stream.avail_out = size;
397413

398414
do {
415+
unsigned char *last_out = stream.next_out;
399416
stream.next_in = fill(1);
400417
stream.avail_in = input_len;
401418
status = git_inflate(&stream, 0);
402419
use(input_len - stream.avail_in);
420+
if (sha1)
421+
git_SHA1_Update(&c, last_out, stream.next_out - last_out);
403422
} while (status == Z_OK);
404423
if (stream.total_out != size || status != Z_STREAM_END)
405424
bad_object(offset, _("inflate returned %d"), status);
406425
git_inflate_end(&stream);
426+
if (sha1)
427+
git_SHA1_Final(sha1, &c);
407428
return buf;
408429
}
409430

410-
static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_base)
431+
static void *unpack_raw_entry(struct object_entry *obj,
432+
union delta_base *delta_base,
433+
unsigned char *sha1)
411434
{
412435
unsigned char *p;
413436
unsigned long size, c;
@@ -467,7 +490,7 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_
467490
}
468491
obj->hdr_size = consumed_bytes - obj->idx.offset;
469492

470-
data = unpack_entry_data(obj->idx.offset, obj->size);
493+
data = unpack_entry_data(obj->idx.offset, obj->size, obj->type, sha1);
471494
obj->idx.crc32 = input_crc32;
472495
return data;
473496
}
@@ -569,9 +592,8 @@ static void find_delta_children(const union delta_base *base,
569592
}
570593

571594
static void sha1_object(const void *data, unsigned long size,
572-
enum object_type type, unsigned char *sha1)
595+
enum object_type type, const unsigned char *sha1)
573596
{
574-
hash_sha1_file(data, size, typename(type), sha1);
575597
read_lock();
576598
if (has_sha1_file(sha1)) {
577599
void *has_data;
@@ -627,11 +649,6 @@ static void sha1_object(const void *data, unsigned long size,
627649
}
628650
}
629651

630-
static int is_delta_type(enum object_type type)
631-
{
632-
return (type == OBJ_REF_DELTA || type == OBJ_OFS_DELTA);
633-
}
634-
635652
/*
636653
* This function is part of find_unresolved_deltas(). There are two
637654
* walkers going in the opposite ways.
@@ -711,6 +728,8 @@ static void resolve_delta(struct object_entry *delta_obj,
711728
free(delta_data);
712729
if (!result->data)
713730
bad_object(delta_obj->idx.offset, _("failed to apply delta"));
731+
hash_sha1_file(result->data, result->size,
732+
typename(delta_obj->real_type), delta_obj->idx.sha1);
714733
sha1_object(result->data, result->size, delta_obj->real_type,
715734
delta_obj->idx.sha1);
716735
counter_lock();
@@ -851,7 +870,7 @@ static void parse_pack_objects(unsigned char *sha1)
851870
nr_objects);
852871
for (i = 0; i < nr_objects; i++) {
853872
struct object_entry *obj = &objects[i];
854-
void *data = unpack_raw_entry(obj, &delta->base);
873+
void *data = unpack_raw_entry(obj, &delta->base, obj->idx.sha1);
855874
obj->real_type = obj->type;
856875
if (is_delta_type(obj->type)) {
857876
nr_deltas++;

0 commit comments

Comments
 (0)