diff --git a/fsck.c b/fsck.c index dd4822ba1b..5acc982a7c 100644 --- a/fsck.c +++ b/fsck.c @@ -308,7 +308,7 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op return -1; name = fsck_get_object_name(options, &tree->object.oid); - if (init_tree_desc_gently(&desc, tree->buffer, tree->size)) + if (init_tree_desc_gently(&desc, tree->buffer, tree->size, 0)) return -1; while (tree_entry_gently(&desc, &entry)) { struct object *obj; @@ -578,7 +578,7 @@ static int fsck_tree(const struct object_id *tree_oid, const char *o_name; struct name_stack df_dup_candidates = { NULL }; - if (init_tree_desc_gently(&desc, buffer, size)) { + if (init_tree_desc_gently(&desc, buffer, size, 0)) { retval += report(options, tree_oid, OBJ_TREE, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree"); diff --git a/packfile.c b/packfile.c index 8e812a84a3..e5b1d0ed76 100644 --- a/packfile.c +++ b/packfile.c @@ -2243,7 +2243,7 @@ static int add_promisor_object(const struct object_id *oid, struct tree *tree = (struct tree *)obj; struct tree_desc desc; struct name_entry entry; - if (init_tree_desc_gently(&desc, tree->buffer, tree->size)) + if (init_tree_desc_gently(&desc, tree->buffer, tree->size, 0)) /* * Error messages are given when packs are * verified, so do not print any here. diff --git a/tree-walk.c b/tree-walk.c index 506234b4b8..74f4d710e8 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -47,17 +47,20 @@ static int decode_tree_entry(struct tree_desc *desc, const char *buf, unsigned l /* Initialize the descriptor entry */ desc->entry.path = path; - desc->entry.mode = canon_mode(mode); + desc->entry.mode = (desc->flags & TREE_DESC_RAW_MODES) ? mode : canon_mode(mode); desc->entry.pathlen = len - 1; oidread(&desc->entry.oid, (const unsigned char *)path + len); return 0; } -static int init_tree_desc_internal(struct tree_desc *desc, const void *buffer, unsigned long size, struct strbuf *err) +static int init_tree_desc_internal(struct tree_desc *desc, const void *buffer, + unsigned long size, struct strbuf *err, + enum tree_desc_flags flags) { desc->buffer = buffer; desc->size = size; + desc->flags = flags; if (size) return decode_tree_entry(desc, buffer, size, err); return 0; @@ -66,15 +69,16 @@ static int init_tree_desc_internal(struct tree_desc *desc, const void *buffer, u void init_tree_desc(struct tree_desc *desc, const void *buffer, unsigned long size) { struct strbuf err = STRBUF_INIT; - if (init_tree_desc_internal(desc, buffer, size, &err)) + if (init_tree_desc_internal(desc, buffer, size, &err, 0)) die("%s", err.buf); strbuf_release(&err); } -int init_tree_desc_gently(struct tree_desc *desc, const void *buffer, unsigned long size) +int init_tree_desc_gently(struct tree_desc *desc, const void *buffer, unsigned long size, + enum tree_desc_flags flags) { struct strbuf err = STRBUF_INIT; - int result = init_tree_desc_internal(desc, buffer, size, &err); + int result = init_tree_desc_internal(desc, buffer, size, &err, flags); if (result) error("%s", err.buf); strbuf_release(&err); diff --git a/tree-walk.h b/tree-walk.h index a5058469e9..6305d53150 100644 --- a/tree-walk.h +++ b/tree-walk.h @@ -34,6 +34,11 @@ struct tree_desc { /* counts the number of bytes left in the `buffer`. */ unsigned int size; + + /* option flags passed via init_tree_desc_gently() */ + enum tree_desc_flags { + TREE_DESC_RAW_MODES = (1 << 0), + } flags; }; /** @@ -79,7 +84,8 @@ int update_tree_entry_gently(struct tree_desc *); */ void init_tree_desc(struct tree_desc *desc, const void *buf, unsigned long size); -int init_tree_desc_gently(struct tree_desc *desc, const void *buf, unsigned long size); +int init_tree_desc_gently(struct tree_desc *desc, const void *buf, unsigned long size, + enum tree_desc_flags flags); /* * Visit the next entry in a tree. Returns 1 when there are more entries