pack v4 trees with a canonical base

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

 



While reviewing the pack v4 thin support Ive realized that some base 
tree objects appended to a thin pack won't be in pack v4 format.  Hence 
the patch below to deal with that possibility.

An eventual optimization to index-pack when completing a pack would be 
to attempt the encoding of appended tree objects into the packv4 format 
using the existing dictionary table in the pack, and fall back to the 
canonical format if that table doesn't have all the necessary elements.

    packv4-parse.c: allow tree entry copying from a canonical tree object
    
    It is possible for a base tree object to be in the canonical
    representation.  This may happen if the encoder detected an irregularity
    preventing a loss free encoding to the pack v4 format, or if a thin pack
    was completed with such tree objects.
    
    Signed-off-by: Nicolas Pitre <nico@xxxxxxxxxxx>

diff --git a/packv4-parse.c b/packv4-parse.c
index c62c4ae..36942bb 100644
--- a/packv4-parse.c
+++ b/packv4-parse.c
@@ -10,6 +10,7 @@
 
 #include "cache.h"
 #include "packv4-parse.h"
+#include "tree-walk.h"
 #include "varint.h"
 
 const unsigned char *get_sha1ref(struct packed_git *p,
@@ -321,6 +322,45 @@ void *pv4_get_commit(struct packed_git *p, struct pack_window **w_curs,
 	return dst;
 }
 
+static int copy_canonical_tree_entries(struct packed_git *p, off_t offset,
+				       unsigned int start, unsigned int count,
+				       unsigned char **dstp, unsigned long *sizep)
+{
+	void *data;
+	const void *from, *end;
+	enum object_type type;
+	unsigned long size;
+	struct tree_desc desc;
+
+	data = unpack_entry(p, offset, &type, &size);
+	if (!data)
+		return -1;
+	if (type != OBJ_TREE) {
+		free(data);
+		return -1;
+	}
+
+	init_tree_desc(&desc, data, size);
+
+	while (start--)
+		update_tree_entry(&desc);
+
+	from = desc.buffer;
+	while (count--)
+		update_tree_entry(&desc);
+	end = desc.buffer;
+
+	if (end - from > *sizep) {
+		free(data);
+		return -1;
+	}
+	memcpy(*dstp, from, end - from);
+	*dstp += end - from;
+	*sizep -= end - from;
+	free(data);
+	return 0;
+}
+
 static int tree_entry_prefix(unsigned char *buf, unsigned long size,
 			     const unsigned char *path, unsigned mode)
 {
@@ -364,7 +404,12 @@ static int decode_entries(struct packed_git *p, struct pack_window **w_curs,
 		while (*scp & 128)
 			if (++scp - src >= avail - 20)
 				return -1;
-		/* let's still make sure this is actually a tree */
+		/* is this a canonical tree object? */
+		if ((*scp & 0xf) == OBJ_TREE)
+			return copy_canonical_tree_entries(p, offset,
+							   start, count,
+							   dstp, sizep);
+		/* let's still make sure this is actually a pv4 tree */
 		if ((*scp++ & 0xf) != OBJ_PV4_TREE)
 			return -1;
 	}
--
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]