summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2013-09-08 14:22:37 +0700
committerNicolas Pitre <nico@fluxnic.net>2013-09-13 21:00:28 -0400
commitf8f5b1697a0b612e64b6f18c84bb6b829e8dd3d7 (patch)
treedca0a1de1736dceb273f699eac40c898c27c1e41
parent5ad027af7fc8957dc4fe7f4b69b9d31be13664ac (diff)
downloadgit-f8f5b1697a0b612e64b6f18c84bb6b829e8dd3d7.tar.gz
index-pack: move delta base queuing code to unpack_raw_entry
For v2, ofs-delta and ref-delta can only have queue one delta base at a time. A v4 tree can have more than one delta base. Move the queuing code up to unpack_raw_entry() and give unpack_tree_v4() more flexibility to add its bases. Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
-rw-r--r--builtin/index-pack.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index b44a462d60..18f64fa6eb 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -568,6 +568,25 @@ static void *unpack_commit_v4(unsigned int offset, unsigned long size,
return dst.buf;
}
+static void add_sha1_delta(struct object_entry *obj,
+ const unsigned char *sha1)
+{
+ struct delta_entry *delta = deltas + nr_deltas;
+ delta->obj_no = obj - objects;
+ hashcpy(delta->base.sha1, sha1);
+ nr_deltas++;
+}
+
+static void add_ofs_delta(struct object_entry *obj,
+ off_t offset)
+{
+ struct delta_entry *delta = deltas + nr_deltas;
+ delta->obj_no = obj - objects;
+ memset(&delta->base, 0, sizeof(delta->base));
+ delta->base.offset = offset;
+ nr_deltas++;
+}
+
/*
* v4 trees are actually kind of deltas and we don't do delta in the
* first pass. This function only walks through a tree object to find
@@ -703,17 +722,16 @@ static void read_typesize_v2(struct object_entry *obj)
}
static void *unpack_raw_entry(struct object_entry *obj,
- union delta_base *delta_base,
unsigned char *sha1)
{
void *data;
- uintmax_t val;
+ off_t offset;
obj->idx.offset = consumed_bytes;
input_crc32 = crc32(0, NULL, 0);
if (packv4) {
- val = read_varint();
+ uintmax_t val = read_varint();
obj->type = val & 15;
obj->size = val >> 4;
} else
@@ -722,14 +740,14 @@ static void *unpack_raw_entry(struct object_entry *obj,
switch (obj->type) {
case OBJ_REF_DELTA:
- hashcpy(delta_base->sha1, fill_and_use(20));
+ add_sha1_delta(obj, fill_and_use(20));
break;
case OBJ_OFS_DELTA:
- memset(delta_base, 0, sizeof(*delta_base));
- val = read_varint();
- delta_base->offset = obj->idx.offset - val;
- if (delta_base->offset <= 0 || delta_base->offset >= obj->idx.offset)
- bad_object(obj->idx.offset, _("delta base offset is out of bound"));
+ offset = obj->idx.offset - read_varint();
+ if (offset <= 0 || offset >= obj->idx.offset)
+ bad_object(obj->idx.offset,
+ _("delta base offset is out of bound"));
+ add_ofs_delta(obj, offset);
break;
case OBJ_COMMIT:
case OBJ_TREE:
@@ -1283,7 +1301,6 @@ static void parse_dictionaries(void)
static void parse_pack_objects(unsigned char *sha1)
{
int i, nr_delays = 0;
- struct delta_entry *delta = deltas;
struct stat st;
if (verbose)
@@ -1292,12 +1309,9 @@ 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, &delta->base, obj->idx.sha1);
- if (is_delta_type(obj->type)) {
- nr_deltas++;
- delta->obj_no = i;
- delta++;
- } else if (!data && obj->type == OBJ_PV4_TREE) {
+ void *data = unpack_raw_entry(obj, obj->idx.sha1);
+ if (is_delta_type(obj->type) ||
+ (!data && obj->type == OBJ_PV4_TREE)) {
/* delay sha1_object() until second pass */
} else if (!data) {
/* large blobs, check later */