X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=pack-objects.c;h=d95f45ebfefc6f696d57b5273ea3f049d4f1ffd2;hb=f3a3214e83be2905c57eff5d9035d169cae4644e;hp=d1e62dc019b46afb4eab076be430381d8fe07c64;hpb=a733cb606fed08130317d803956e946f73b0b88e;p=git.git diff --git a/pack-objects.c b/pack-objects.c index d1e62dc01..d95f45ebf 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -34,7 +34,7 @@ static void *delta_against(void *buf, unsigned long size, struct object_entry *e if (!otherbuf) die("unable to read %s", sha1_to_hex(entry->delta->sha1)); delta_buf = diff_delta(otherbuf, othersize, - buf, size, &delta_size, ~0UL); + buf, size, &delta_size, 0); if (!delta_buf || delta_size != entry->delta_size) die("delta size changed"); free(buf); @@ -51,32 +51,19 @@ static void *delta_against(void *buf, unsigned long size, struct object_entry *e */ static int encode_header(enum object_type type, unsigned long size, unsigned char *hdr) { - int n = 1, i; + int n = 1; unsigned char c; if (type < OBJ_COMMIT || type > OBJ_DELTA) die("bad type %d", type); - /* - * Shift the size up by 7 bits at a time, - * until you get bits in the "high four". - * That will be our beginning. We'll have - * four size bits in 28..31, then groups - * of seven in 21..27, 14..20, 7..13 and - * finally 0..6. - */ - if (size) { - n = 5; - while (!(size & 0xfe000000)) { - size <<= 7; - n--; - } - } - c = (type << 4) | (size >> 28); - for (i = 1; i < n; i++) { + c = (type << 4) | (size & 15); + size >>= 4; + while (size) { *hdr++ = c | 0x80; - c = (size >> 21) & 0x7f; - size <<= 7; + c = size & 0x7f; + size >>= 7; + n++; } *hdr = c; return n; @@ -97,9 +84,9 @@ static unsigned long write_object(struct sha1file *f, struct object_entry *entry die("object %s size inconsistency (%lu vs %lu)", sha1_to_hex(entry->sha1), size, entry->size); /* - * The object header is a byte of 'type' followed by four bytes of - * length, except for deltas that has the 20 bytes of delta sha - * instead. + * The object header is a byte of 'type' followed by zero or + * more bytes of length. For deltas, the 20 bytes of delta sha1 + * follows that. */ obj_type = entry->type; if (entry->delta) { @@ -118,6 +105,23 @@ static unsigned long write_object(struct sha1file *f, struct object_entry *entry return hdrlen + datalen; } +static unsigned long write_one(struct sha1file *f, + struct object_entry *e, + unsigned long offset) +{ + if (e->offset) + /* offset starts from header size and cannot be zero + * if it is written already. + */ + return offset; + e->offset = offset; + offset += write_object(f, e); + /* if we are delitified, write out its base object. */ + if (e->delta) + offset = write_one(f, e->delta, offset); + return offset; +} + static void write_pack_file(void) { int i; @@ -131,15 +135,13 @@ static void write_pack_file(void) else f = sha1create("%s.%s", base_name, "pack"); hdr.hdr_signature = htonl(PACK_SIGNATURE); - hdr.hdr_version = htonl(1); + hdr.hdr_version = htonl(PACK_VERSION); hdr.hdr_entries = htonl(nr_objects); sha1write(f, &hdr, sizeof(hdr)); offset = sizeof(hdr); - for (i = 0; i < nr_objects; i++) { - struct object_entry *entry = objects + i; - entry->offset = offset; - offset += write_object(f, entry); - } + for (i = 0; i < nr_objects; i++) + offset = write_one(f, objects + i, offset); + sha1close(f, pack_file_sha1, 1); mb = offset >> 20; offset &= 0xfffff;