Signed-off-by: Nguyán ThÃi Ngác Duy <pclouds@xxxxxxxxx> --- because tree_entry_interesting() will need writable "base". builtin/grep.c | 59 +++++++++++++++++++++++++++++-------------------------- 1 files changed, 31 insertions(+), 28 deletions(-) diff --git a/builtin/grep.c b/builtin/grep.c index 1646e15..6bd5728 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -623,44 +623,38 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int return hit; } +/* + * "base" is a writable buffer where + * - base[-tree_name_len..-1] contains tree_name + * - base[0..baselen-1] contains tree base + */ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, - struct tree_desc *tree, - const char *tree_name, const char *base) + struct tree_desc *tree, char *base, + int baselen, int tree_name_len) { - int len; int hit = 0; struct name_entry entry; - char *down; - int tn_len = strlen(tree_name); - struct strbuf pathbuf; - - strbuf_init(&pathbuf, PATH_MAX + tn_len); - - if (tn_len) { - strbuf_add(&pathbuf, tree_name, tn_len); - strbuf_addch(&pathbuf, ':'); - tn_len = pathbuf.len; - } - strbuf_addstr(&pathbuf, base); - len = pathbuf.len; while (tree_entry(tree, &entry)) { int te_len = tree_entry_len(entry.path, entry.sha1); - pathbuf.len = len; - strbuf_add(&pathbuf, entry.path, te_len); + int len = baselen; + memcpy(base + baselen, entry.path, te_len+1); - if (S_ISDIR(entry.mode)) + len += te_len; + if (S_ISDIR(entry.mode)) { /* Match "abc/" against pathspec to * decide if we want to descend into "abc" * directory. */ - strbuf_addch(&pathbuf, '/'); + base[len++] = '/'; + base[len] = 0; + } - down = pathbuf.buf + tn_len; - if (!pathspec_matches(pathspec->raw, down, opt->max_depth)) + if (!pathspec_matches(pathspec->raw, base, opt->max_depth)) ; - else if (S_ISREG(entry.mode)) - hit |= grep_sha1(opt, entry.sha1, pathbuf.buf, tn_len); + else if (S_ISREG(entry.mode)) { + hit |= grep_sha1(opt, entry.sha1, base-tree_name_len, tree_name_len); + } else if (S_ISDIR(entry.mode)) { enum object_type type; struct tree_desc sub; @@ -672,13 +666,12 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, die("unable to read tree (%s)", sha1_to_hex(entry.sha1)); init_tree_desc(&sub, data, size); - hit |= grep_tree(opt, pathspec, &sub, tree_name, down); + hit |= grep_tree(opt, pathspec, &sub, base, len, tree_name_len); free(data); } if (hit && opt->status_only) break; } - strbuf_release(&pathbuf); return hit; } @@ -691,13 +684,23 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec, struct tree_desc tree; void *data; unsigned long size; - int hit; + int hit, len; + char *base; + data = read_object_with_reference(obj->sha1, tree_type, &size, NULL); if (!data) die("unable to read tree (%s)", sha1_to_hex(obj->sha1)); init_tree_desc(&tree, data, size); - hit = grep_tree(opt, pathspec, &tree, name, ""); + len = name ? strlen(name) : 0; + base = xmalloc(PATH_MAX + len + 1); + if (len) { + memcpy(base, name, len); + base[len++] = ':'; + } + base[len] = 0; + hit = grep_tree(opt, pathspec, &tree, base+len, 0, len); + free(base); free(data); return hit; } -- 1.7.3.3.476.g10a82 -- 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