diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2013-09-09 20:58:05 +0700 |
---|---|---|
committer | Nicolas Pitre <nico@fluxnic.net> | 2013-09-13 21:00:29 -0400 |
commit | 99e842643417dfe238f40c19c50c7eaffb8c0e4d (patch) | |
tree | fb8af69d8661642e14bbe0b7424f0117c246eb63 | |
parent | fa7e4e65ff84dae1da69a633126f062999431875 (diff) | |
download | git-99e842643417dfe238f40c19c50c7eaffb8c0e4d.tar.gz |
pack v4: support "end-of-pack" indicator in index-pack and pack-objects
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@gmail.com>
Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
-rw-r--r-- | builtin/index-pack.c | 29 | ||||
-rw-r--r-- | 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 059fe3db21..c97c051a80 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1494,7 +1494,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) @@ -1503,7 +1503,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) { @@ -1522,8 +1543,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 1e118660c7..39d1e088fb 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -866,15 +866,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 < v4.all_objs_nr) + 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); |