Re: [PATCH v3] Document pack v4 format

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

 



On Fri, 6 Sep 2013, Nguyễn Thái Ngọc Duy wrote:

> 
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx>
> ---
>  Should be up to date with Nico's latest implementation and also cover
>  additions to the format that everybody seems to agree on:
> 
>   - new types for canonical trees and commits
>   - sha-1 table covering missing objects in thin packs

Yes, I've tweaked the format again.  I've implemented the code needed to 
carry canonical commit and tree objects in pack v4.  And things are much 
simpler if the canonical commit and tree types are identical to pack v2.  
Therefore the new types are used for the pack v4 optimized commit and 
tree representations.

I've therefore added this patch to my tree (with the needed changes to 
the documentation patch):

commit 98d4b75aff266015b5dff0a324a2984c2a8f7fa2
Author: Nicolas Pitre <nico@xxxxxxxxxxx>
Date:   Fri Sep 6 23:45:49 2013 -0400

    pack v4: allow canonical commit and tree objects
    
    If for some reason we can't transcode a commit or tree object (lossy
    encoding such as the zero-padded file mode for example) then we can still
    store the canonical object like in pack v2.
    
    This is also useful for completing a thin pack without having to add
    missing entries to the dictionary tables.
    
    To simplify things, the canonical commit and tree types retain their type
    number 1 and 2 respectively, and the transcoded types are now 9 and 10
    i.e. with bit 3 added.
    
    Signed-off-by: Nicolas Pitre <nico@xxxxxxxxxxx>

diff --git a/cache.h b/cache.h
index a6d016b..b68ad5a 100644
--- a/cache.h
+++ b/cache.h
@@ -330,6 +330,8 @@ enum object_type {
 	/* 5 for future expansion */
 	OBJ_OFS_DELTA = 6,
 	OBJ_REF_DELTA = 7,
+	OBJ_PV4_COMMIT = (8 + 1),
+	OBJ_PV4_TREE = (8 + 2),
 	OBJ_ANY,
 	OBJ_MAX
 };
diff --git a/packv4-create.c b/packv4-create.c
index 11cfe6f..38fa594 100644
--- a/packv4-create.c
+++ b/packv4-create.c
@@ -981,10 +981,15 @@ static off_t packv4_write_object(struct sha1file *f, struct packed_git *p,
 		die("unexpected object type %d", type);
 	}
 	free(src);
-	if (!result)
-		die("can't convert %s object %s",
-		    typename(type), sha1_to_hex(obj->sha1));
+	if (!result) {
+		warning("can't convert %s object %s",
+			typename(type), sha1_to_hex(obj->sha1));
+		/* fall back to copy the object in its original form */
+		return copy_object_data(f, p, obj->offset);
+	}
 
+	/* Use bit 3 to indicate a special type encoding */
+	type += 8;
 	hdrlen = write_object_header(f, type, obj_size);
 	sha1write(f, result, buf_size);
 	free(result);
diff --git a/packv4-parse.c b/packv4-parse.c
index 86ec535..63bba03 100644
--- a/packv4-parse.c
+++ b/packv4-parse.c
@@ -266,7 +266,7 @@ static int decode_entries(struct packed_git *p, struct pack_window **w_curs,
 			if (++scp - src >= avail - 20)
 				return -1;
 		/* let's still make sure this is actually a tree */
-		if ((*scp++ & 0xf) != OBJ_TREE)
+		if ((*scp++ & 0xf) != OBJ_PV4_TREE)
 			return -1;
 	}
 
diff --git a/sha1_file.c b/sha1_file.c
index 79e1293..c7bf677 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1806,6 +1806,11 @@ static enum object_type packed_to_object_type(struct packed_git *p,
 	}
 
 	switch (type) {
+	case OBJ_PV4_COMMIT:
+	case OBJ_PV4_TREE:
+		/* hide pack v4 special object types */
+		type -= 8;
+		break;
 	case OBJ_BAD:
 	case OBJ_COMMIT:
 	case OBJ_TREE:
@@ -2171,17 +2176,16 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
 		if (data)
 			die("BUG in unpack_entry: left loop at a valid delta");
 		break;
+	case OBJ_PV4_COMMIT:
+		data = pv4_get_commit(p, &w_curs, curpos, size);
+		type -= 8;
+		break;
+	case OBJ_PV4_TREE:
+		data = pv4_get_tree(p, &w_curs, curpos, size);
+		type -= 8;
+		break;
 	case OBJ_COMMIT:
 	case OBJ_TREE:
-		if (p->version >= 4 && !base_from_cache) {
-			if (type == OBJ_COMMIT) {
-				data = pv4_get_commit(p, &w_curs, curpos, size);
-			} else {
-				data = pv4_get_tree(p, &w_curs, curpos, size);
-			}
-			break;
-		}
-		/* fall through */
 	case OBJ_BLOB:
 	case OBJ_TAG:
 		if (!base_from_cache)


[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]