Code

remove delta-against-self bit
authorNicolas Pitre <nico@cam.org>
Thu, 9 Feb 2006 22:50:04 +0000 (17:50 -0500)
committerJunio C Hamano <junkio@cox.net>
Fri, 10 Feb 2006 05:06:38 +0000 (21:06 -0800)
After experimenting with code to add the ability to encode a delta
against part of the deltified file, it turns out that resulting packs
are _bigger_ than when this ability is not used.  The raw delta output
might be smaller, but it doesn't compress as well using gzip with a
negative net saving on average.

Said bit would in fact be more useful to allow for encoding the copying
of chunks larger than 64KB providing more savings with large files.
This will correspond to packs version 3.

While the current code still produces packs version 2, it is made future
proof so pack versions 2 and 3 are accepted.  Any pack version 2 are
compatible with version 3 since the redefined bit was never used before.
When enough time has passed, code to use that bit to produce version 3
packs could be added.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
index-pack.c
pack-check.c
pack.h
patch-delta.c
unpack-objects.c

index 541d7bc1c1723c1a41cd35349b607223c94a4dca..babe34b2db520a311d6c8ef090383755ba1807c9 100644 (file)
@@ -68,9 +68,9 @@ static void parse_pack_header(void)
        hdr = (void *)pack_base;
        if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
                die("packfile '%s' signature mismatch", pack_name);
-       if (hdr->hdr_version != htonl(PACK_VERSION))
-               die("packfile '%s' version %d different from ours %d",
-                   pack_name, ntohl(hdr->hdr_version), PACK_VERSION);
+       if (!pack_version_ok(hdr->hdr_version))
+               die("packfile '%s' version %d unsupported",
+                   pack_name, ntohl(hdr->hdr_version));
 
        nr_objects = ntohl(hdr->hdr_entries);
 
index 511f29424a622f62035f1cd3428aeca7ee18f0e2..67a7ecdf16a39000ffa9ed3453854607bc1e141d 100644 (file)
@@ -16,9 +16,9 @@ static int verify_packfile(struct packed_git *p)
        hdr = p->pack_base;
        if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
                return error("Packfile %s signature mismatch", p->pack_name);
-       if (hdr->hdr_version != htonl(PACK_VERSION))
-               return error("Packfile version %d different from ours %d",
-                            ntohl(hdr->hdr_version), PACK_VERSION);
+       if (!pack_version_ok(hdr->hdr_version))
+               return error("Packfile version %d unsupported",
+                            ntohl(hdr->hdr_version));
        nr_objects = ntohl(hdr->hdr_entries);
        if (num_packed_objects(p) != nr_objects)
                return error("Packfile claims to have %d objects, "
diff --git a/pack.h b/pack.h
index 657deaa3f43ebe8627caa93798dd8ae5d956601d..9dafa2b6d2c76919594218b12a2a36bd9067f2b7 100644 (file)
--- a/pack.h
+++ b/pack.h
@@ -21,6 +21,7 @@ enum object_type {
  */
 #define PACK_SIGNATURE 0x5041434b      /* "PACK" */
 #define PACK_VERSION 2
+#define pack_version_ok(v) ((v) == htonl(2) || (v) == htonl(3))
 struct pack_header {
        unsigned int hdr_signature;
        unsigned int hdr_version;
index 98c27beb252420102de78e50994ed5cc5b6f564a..c0e13114351c4ea427ddfe4d9e9c20a541201ad6 100644 (file)
@@ -44,16 +44,15 @@ void *patch_delta(void *src_buf, unsigned long src_size,
                cmd = *data++;
                if (cmd & 0x80) {
                        unsigned long cp_off = 0, cp_size = 0;
-                       const unsigned char *buf;
                        if (cmd & 0x01) cp_off = *data++;
                        if (cmd & 0x02) cp_off |= (*data++ << 8);
                        if (cmd & 0x04) cp_off |= (*data++ << 16);
                        if (cmd & 0x08) cp_off |= (*data++ << 24);
                        if (cmd & 0x10) cp_size = *data++;
                        if (cmd & 0x20) cp_size |= (*data++ << 8);
+                       if (cmd & 0x40) cp_size |= (*data++ << 16);
                        if (cp_size == 0) cp_size = 0x10000;
-                       buf = (cmd & 0x40) ? dst_buf : src_buf;
-                       memcpy(out, buf + cp_off, cp_size);
+                       memcpy(out, src_buf + cp_off, cp_size);
                        out += cp_size;
                } else {
                        memcpy(out, data, cmd);
index 4b5b5cb3e22454fe487002f698272a19a1d8861d..815a1b382b1f92686efd00bee5794a8480d7f7b7 100644 (file)
@@ -246,13 +246,12 @@ static void unpack_all(void)
 {
        int i;
        struct pack_header *hdr = fill(sizeof(struct pack_header));
-       unsigned version = ntohl(hdr->hdr_version);
        unsigned nr_objects = ntohl(hdr->hdr_entries);
 
        if (ntohl(hdr->hdr_signature) != PACK_SIGNATURE)
                die("bad pack file");
-       if (version != PACK_VERSION)
-               die("unable to handle pack file version %d", version);
+       if (!pack_version_ok(hdr->hdr_version))
+               die("unknown pack file version %d", ntohl(hdr->hdr_version));
        fprintf(stderr, "Unpacking %d objects\n", nr_objects);
 
        use(sizeof(struct pack_header));