When PV4_TREE_CANONICAL is passed, decode_entries() generates <count> tree entries in canonical format. When this flag is not passed _and_ count is 1, decode_entries fills struct name_entry and saves sha1_index. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- packv4-parse.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- packv4-parse.h | 10 ++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/packv4-parse.c b/packv4-parse.c index f5c486e..f222456 100644 --- a/packv4-parse.c +++ b/packv4-parse.c @@ -365,6 +365,12 @@ static int copy_canonical_tree_entries(struct pv4_tree_desc *v4, off_t offset, while (start--) update_tree_entry(desc); + if (!(v4->flags & PV4_TREE_CANONICAL)) { + v4->sha1_index = 0; + v4->pathlen = tree_entry_len(&desc->entry); + return 0; + } + from = desc->buffer; while (count--) update_tree_entry(desc); @@ -462,6 +468,33 @@ static int generate_tree_entry(struct pv4_tree_desc *desc, return 0; } +static int get_tree_entry_v4(struct pv4_tree_desc *desc, + const unsigned char **bufp, + int what) +{ + const unsigned char *path; + + path = get_pathref(desc->p, what >> 1, &desc->pathlen); + if (!path) + return -1; + desc->v2.entry.mode = (path[0] << 8) | path[1]; + desc->v2.entry.path = (const char *)path + 2; + + if (**bufp) { + desc->sha1_index = decode_varint(bufp); + if (desc->sha1_index < 1 || + desc->sha1_index - 1 > desc->p->num_objects) + return error("bad index in get_sha1ref"); + desc->v2.entry.sha1 = desc->p->sha1_table + (desc->sha1_index - 1) * 20; + } else { + desc->sha1_index = 0; + desc->v2.entry.sha1 = *bufp + 1; + *bufp += 21; + } + + return 0; +} + static int decode_entries(struct pv4_tree_desc *desc, off_t obj_offset, unsigned int start, unsigned int count) { @@ -561,8 +594,14 @@ static int decode_entries(struct pv4_tree_desc *desc, off_t obj_offset, /* * This is an actual tree entry to recreate. */ - if (generate_tree_entry(desc, &scp, what)) - return -1; + if (desc->flags & PV4_TREE_CANONICAL) { + if (generate_tree_entry(desc, &scp, what)) + return -1; + } else if (count == 1) { + if (get_tree_entry_v4(desc, &scp, what)) + return -1; + } else + die("generating multiple v4 entries is not supported"); count--; curpos++; } else if (what & 1) { @@ -668,6 +707,7 @@ void *pv4_get_tree(struct packed_git *p, struct pack_window **w_curs, int ret; memset(&desc, 0, sizeof(desc)); + desc.flags = PV4_TREE_CANONICAL; desc.p = p; desc.w_curs = *w_curs; strbuf_init(&desc.buf, size); diff --git a/packv4-parse.h b/packv4-parse.h index 04b9a59..fe0ea38 100644 --- a/packv4-parse.h +++ b/packv4-parse.h @@ -24,10 +24,20 @@ void *pv4_get_commit(struct packed_git *p, struct pack_window **w_curs, void *pv4_get_tree(struct packed_git *p, struct pack_window **w_curs, off_t obj_offset, unsigned long size); +/* + * These are private flags, never pass them directly to + * pv4_tree_desc_* + */ +#define PV4_TREE_CANONICAL 0x800 + struct pv4_tree_desc { + unsigned flags; + /* v4 entry */ struct packed_git *p; struct pack_window *w_curs; + unsigned int sha1_index; + int pathlen; /* v2 entry */ struct tree_desc v2; -- 1.8.2.83.gc99314b -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html