diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2013-09-11 13:06:17 +0700 |
---|---|---|
committer | Nicolas Pitre <nico@fluxnic.net> | 2013-09-13 21:00:31 -0400 |
commit | 51b469cf6b7e62a594aae2f67a47ec48c29a06e1 (patch) | |
tree | dc0770cc52108cbee89878420762ecce9df1367a | |
parent | d4ed92abc5b4220adf371b463715d1694fb77243 (diff) | |
download | git-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.c | 60 |
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; |