In v2, the number of objects in the pack header indicates how many objects are sent. In v4 this is no longer true, that number includes the base objects ommitted by pack-objects. An "end-of-pack" is inserted just before the final SHA-1 to let index-pack knows when to stop. The EOP is zero (in variable length encoding it means type zero, OBJ_NONE, and size zero) Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- builtin/index-pack.c | 29 +++++++++++++++++++++++++---- builtin/pack-objects.c | 15 +++++++++++---- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 88340b5..9036f3e 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1493,7 +1493,7 @@ static void parse_dictionaries(void) */ static void parse_pack_objects(unsigned char *sha1) { - int i, nr_delays = 0; + int i, nr_delays = 0, eop = 0; struct stat st; if (verbose) @@ -1502,7 +1502,28 @@ static void parse_pack_objects(unsigned char *sha1) nr_objects); for (i = 0; i < nr_objects; i++) { struct object_entry *obj = &objects[i]; - void *data = unpack_raw_entry(obj, obj->idx.sha1); + void *data; + + if (packv4) { + unsigned char *eop_byte; + flush(); + /* Got End-of-Pack signal? */ + eop_byte = fill(1); + if (*eop_byte == 0) { + git_SHA1_Update(&input_ctx, eop_byte, 1); + use(1); + /* + * consumed by is used to mark the end + * of the object right after this + * loop. Undo use() effect. + */ + consumed_bytes--; + eop = 1; /* so we don't flush() again */ + break; + } + } + + data = unpack_raw_entry(obj, obj->idx.sha1); if (is_delta_type(obj->type) || is_delta_tree(obj)) { /* delay sha1_object() until second pass */ } else if (!data) { @@ -1521,8 +1542,8 @@ static void parse_pack_objects(unsigned char *sha1) objects[i].idx.offset = consumed_bytes; stop_progress(&progress); - /* Check pack integrity */ - flush(); + if (!eop) + flush(); /* Check pack integrity */ git_SHA1_Final(sha1, &input_ctx); if (hashcmp(fill(20), sha1)) die(_("pack is corrupted (SHA1 mismatch)")); diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 12d9af4..1efb728 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -865,15 +865,22 @@ static void write_pack_file(void) display_progress(progress_state, written); } - /* - * Did we write the wrong # entries in the header? - * If so, rewrite it like in fast-import - */ if (pack_to_stdout) { + unsigned char type_zero = 0; + /* + * Pack v4 thin pack is terminated by a "type + * 0, size 0" in variable length encoding + */ + if (pack_version == 4 && nr_written < nr_objects) + sha1write(f, &type_zero, 1); sha1close(f, sha1, CSUM_CLOSE); } else if (nr_written == nr_remaining) { sha1close(f, sha1, CSUM_FSYNC); } else { + /* + * Did we write the wrong # entries in the header? + * If so, rewrite it like in fast-import + */ int fd = sha1close(f, sha1, 0); fixup_pack_header_footer(fd, sha1, pack_tmp_name, nr_written, sha1, offset); -- 1.8.2.83.gc99314b -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html