[PATCH v2 14/16] pack v4: support "end-of-pack" indicator in index-pack and pack-objects

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]