summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2013-09-11 13:06:17 +0700
committerNicolas Pitre <nico@fluxnic.net>2013-09-13 21:00:31 -0400
commit51b469cf6b7e62a594aae2f67a47ec48c29a06e1 (patch)
treedc0770cc52108cbee89878420762ecce9df1367a
parentd4ed92abc5b4220adf371b463715d1694fb77243 (diff)
downloadgit-51b469cf6b7e62a594aae2f67a47ec48c29a06e1.tar.gz
unpack-objects: decode v4 commits
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
-rw-r--r--builtin/unpack-objects.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index f8442f4e89..6fc72c149c 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -131,6 +131,15 @@ static const unsigned char *read_sha1ref(void)
return sha1_table + index * 20;
}
+static const unsigned char *read_dictref(struct packv4_dict *dict)
+{
+ unsigned int index = read_varint();
+ if (index >= dict->nb_entries)
+ die("bad index in read_dictref at %lu",
+ (unsigned long)consumed_bytes);
+ return dict->data + dict->offsets[index];
+}
+
static void *get_data(unsigned long size)
{
git_zstream stream;
@@ -467,6 +476,54 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
free(base);
}
+static void unpack_commit_v4(unsigned long size, unsigned long nr)
+{
+ unsigned int nb_parents;
+ const unsigned char *committer, *author, *ident;
+ unsigned long author_time, committer_time;
+ int16_t committer_tz, author_tz;
+ struct strbuf dst;
+ char *remaining;
+
+ strbuf_init(&dst, size);
+
+ strbuf_addf(&dst, "tree %s\n", sha1_to_hex(read_sha1ref()));
+ nb_parents = read_varint();
+ while (nb_parents--)
+ strbuf_addf(&dst, "parent %s\n", sha1_to_hex(read_sha1ref()));
+
+ committer_time = read_varint();
+ ident = read_dictref(name_dict);
+ committer_tz = (ident[0] << 8) | ident[1];
+ committer = ident + 2;
+
+ author_time = read_varint();
+ ident = read_dictref(name_dict);
+ author_tz = (ident[0] << 8) | ident[1];
+ author = ident + 2;
+
+ if (author_time & 1)
+ author_time = committer_time + (author_time >> 1);
+ else
+ author_time = committer_time - (author_time >> 1);
+
+ strbuf_addf(&dst,
+ "author %s %lu %+05d\n"
+ "committer %s %lu %+05d\n",
+ author, author_time, author_tz,
+ committer, committer_time, committer_tz);
+
+ if (dst.len > size)
+ die("bad commit");
+
+ remaining = get_data(size - dst.len);
+ strbuf_add(&dst, remaining, size - dst.len);
+ if (!dry_run)
+ write_object(nr, OBJ_COMMIT, dst.buf, dst.len);
+ else
+ strbuf_release(&dst);
+}
+
static void read_typesize_v2(enum object_type *type, unsigned long *size)
{
unsigned char c = *(char*)fill_and_use(1);
@@ -511,6 +568,9 @@ static int unpack_one(unsigned nr)
case OBJ_OFS_DELTA:
unpack_delta_entry(type, size, nr);
break;
+ case OBJ_PV4_COMMIT:
+ unpack_commit_v4(size, nr);
+ break;
default:
error("bad object type %d", type);
has_errors = 1;