X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=tree-walk.c;h=9f7abb7cb352241191e395e3967730f3bdcf6d55;hb=aae01bda7f6d3224cf6b2ce0aa9aa668ce35d0b7;hp=0735f4046dd8524e92e97a8ce6cc5c0991208b01;hpb=f0c979f4dbbb7d6d9565d945c540f0a5748f1b80;p=git.git diff --git a/tree-walk.c b/tree-walk.c index 0735f404..9f7abb7c 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -1,5 +1,6 @@ #include "cache.h" #include "tree-walk.h" +#include "tree.h" void *fill_tree_descriptor(struct tree_desc *desc, const unsigned char *sha1) { @@ -7,7 +8,7 @@ void *fill_tree_descriptor(struct tree_desc *desc, const unsigned char *sha1) void *buf = NULL; if (sha1) { - buf = read_object_with_reference(sha1, "tree", &size, NULL); + buf = read_object_with_reference(sha1, tree_type, &size, NULL); if (!buf) die("unable to read tree %s", sha1_to_hex(sha1)); } @@ -114,3 +115,53 @@ void traverse_trees(int n, struct tree_desc *t, const char *base, traverse_callb free(entry); } +static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char *result, unsigned *mode) +{ + int namelen = strlen(name); + while (t->size) { + const char *entry; + const unsigned char *sha1; + int entrylen, cmp; + + sha1 = tree_entry_extract(t, &entry, mode); + update_tree_entry(t); + entrylen = strlen(entry); + if (entrylen > namelen) + continue; + cmp = memcmp(name, entry, entrylen); + if (cmp > 0) + continue; + if (cmp < 0) + break; + if (entrylen == namelen) { + memcpy(result, sha1, 20); + return 0; + } + if (name[entrylen] != '/') + continue; + if (!S_ISDIR(*mode)) + break; + if (++entrylen == namelen) { + memcpy(result, sha1, 20); + return 0; + } + return get_tree_entry(sha1, name + entrylen, result, mode); + } + return -1; +} + +int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned char *sha1, unsigned *mode) +{ + int retval; + void *tree; + struct tree_desc t; + + tree = read_object_with_reference(tree_sha1, tree_type, &t.size, NULL); + if (!tree) + return -1; + t.buf = tree; + retval = find_tree_entry(&t, name, sha1, mode); + free(tree); + return retval; +} +