summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-29 05:15:57 (GMT)
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-29 05:15:57 (GMT)
commit01247d87421d621db3866ce7f2124784fc7f46e5 (patch)
tree713dd383b2677965636ec93bb694dcdd8269227c
parent69a2d426f0d249bca2c6f754b3c1283c0fa72fd4 (diff)
downloadgit-01247d87421d621db3866ce7f2124784fc7f46e5.zip
git-01247d87421d621db3866ce7f2124784fc7f46e5.tar.gz
git-01247d87421d621db3866ce7f2124784fc7f46e5.tar.bz2
Make git pack files use little-endian size encoding
This makes it match the new delta encoding, and admittedly makes the code easier to follow. This also updates the PACK file version to 2, since this (and the delta encoding change in the previous commit) are incompatible with the old format.
-rw-r--r--Makefile2
-rw-r--r--pack-objects.c29
-rw-r--r--pack.h19
-rw-r--r--sha1_file.c5
-rw-r--r--unpack-objects.c7
5 files changed, 31 insertions, 31 deletions
diff --git a/Makefile b/Makefile
index 1736980..9384c53 100644
--- a/Makefile
+++ b/Makefile
@@ -47,7 +47,7 @@ LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o \
tag.o date.o index.o diff-delta.o patch-delta.o entry.o \
epoch.o refs.o csum-file.o
LIB_FILE=libgit.a
-LIB_H=cache.h object.h blob.h tree.h commit.h tag.h delta.h epoch.h csum-file.h
+LIB_H=cache.h object.h blob.h tree.h commit.h tag.h delta.h epoch.h csum-file.h pack.h
LIB_H += strbuf.h
LIB_OBJS += strbuf.o
diff --git a/pack-objects.c b/pack-objects.c
index feee560..fc969e3 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -51,32 +51,19 @@ static void *delta_against(void *buf, unsigned long size, struct object_entry *e
*/
static int encode_header(enum object_type type, unsigned long size, unsigned char *hdr)
{
- int n = 1, i;
+ int n = 1;
unsigned char c;
if (type < OBJ_COMMIT || type > OBJ_DELTA)
die("bad type %d", type);
- /*
- * Shift the size up by 7 bits at a time,
- * until you get bits in the "high four".
- * That will be our beginning. We'll have
- * four size bits in 28..31, then groups
- * of seven in 21..27, 14..20, 7..13 and
- * finally 0..6.
- */
- if (size) {
- n = 5;
- while (!(size & 0xfe000000)) {
- size <<= 7;
- n--;
- }
- }
- c = (type << 4) | (size >> 28);
- for (i = 1; i < n; i++) {
+ c = (type << 4) | (size & 15);
+ size >>= 4;
+ while (size) {
*hdr++ = c | 0x80;
- c = (size >> 21) & 0x7f;
- size <<= 7;
+ c = size & 0x7f;
+ size >>= 7;
+ n++;
}
*hdr = c;
return n;
@@ -148,7 +135,7 @@ static void write_pack_file(void)
else
f = sha1create("%s.%s", base_name, "pack");
hdr.hdr_signature = htonl(PACK_SIGNATURE);
- hdr.hdr_version = htonl(1);
+ hdr.hdr_version = htonl(PACK_VERSION);
hdr.hdr_entries = htonl(nr_objects);
sha1write(f, &hdr, sizeof(hdr));
offset = sizeof(hdr);
diff --git a/pack.h b/pack.h
index 08e120d..83ac321 100644
--- a/pack.h
+++ b/pack.h
@@ -1,19 +1,26 @@
#ifndef PACK_H
#define PACK_H
+/*
+ * The packed object type is stored in 3 bits.
+ * The type value 0 is a reserved prefix if ever there is more than 7
+ * object types, or any future format extensions.
+ */
enum object_type {
- OBJ_NONE,
- OBJ_COMMIT,
- OBJ_TREE,
- OBJ_BLOB,
- OBJ_TAG,
- OBJ_DELTA,
+ OBJ_EXT = 0,
+ OBJ_COMMIT = 1,
+ OBJ_TREE = 2,
+ OBJ_BLOB = 3,
+ OBJ_TAG = 4,
+ /* 5/6 for future expansion */
+ OBJ_DELTA = 7,
};
/*
* Packed object header
*/
#define PACK_SIGNATURE 0x5041434b /* "PACK" */
+#define PACK_VERSION 2
struct pack_header {
unsigned int hdr_signature;
unsigned int hdr_version;
diff --git a/sha1_file.c b/sha1_file.c
index 25208d2..0bdaa16 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -659,6 +659,7 @@ static int packed_delta_info(unsigned char *base_sha1,
static unsigned long unpack_object_header(struct packed_git *p, unsigned long offset,
enum object_type *type, unsigned long *sizep)
{
+ unsigned shift;
unsigned char *pack, c;
unsigned long size;
@@ -670,12 +671,14 @@ static unsigned long unpack_object_header(struct packed_git *p, unsigned long of
offset++;
*type = (c >> 4) & 7;
size = c & 15;
+ shift = 4;
while (c & 0x80) {
if (offset >= p->pack_size)
die("object offset outside of pack file");
c = *pack++;
offset++;
- size = (size << 7) | (c & 0x7f);
+ size += (c & 0x7f) << shift;
+ shift += 7;
}
*sizep = size;
return offset;
diff --git a/unpack-objects.c b/unpack-objects.c
index 0892d2b..b9ddcb7 100644
--- a/unpack-objects.c
+++ b/unpack-objects.c
@@ -183,6 +183,7 @@ static int unpack_delta_entry(unsigned long delta_size)
static void unpack_one(void)
{
+ unsigned shift;
unsigned char *pack, c;
unsigned long size;
enum object_type type;
@@ -192,11 +193,13 @@ static void unpack_one(void)
use(1);
type = (c >> 4) & 7;
size = (c & 15);
+ shift = 4;
while (c & 0x80) {
pack = fill(1);
c = *pack++;
use(1);
- size = (size << 7) + (c & 0x7f);
+ size += (c & 0x7f) << shift;
+ shift += 7;
}
switch (type) {
case OBJ_COMMIT:
@@ -227,7 +230,7 @@ static void unpack_all(void)
if (ntohl(hdr->hdr_signature) != PACK_SIGNATURE)
die("bad pack file");
- if (version != 1)
+ if (version != PACK_VERSION)
die("unable to handle pack file version %d", version);
fprintf(stderr, "Unpacking %d objects\n", nr_objects);