static int grep_tree(struct grep_opt *opt, const char **paths, struct tree_desc *tree, const char *tree_name, const char *base) { 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); if (S_ISDIR(entry.mode)) /* Match "abc/" against pathspec to * decide if we want to descend into "abc" * directory. */ strbuf_addch(&pathbuf, '/'); down = pathbuf.buf + tn_len; if (!pathspec_matches(paths, down, opt->max_depth)) ; else if (S_ISREG(entry.mode)) hit |= grep_sha1(opt, entry.sha1, pathbuf.buf, tn_len); else if (S_ISDIR(entry.mode)) { enum object_type type; struct tree_desc sub; void *data; unsigned long size; data = lock_and_read_sha1_file(entry.sha1, &type, &size); if (!data) die("unable to read tree (%s)", sha1_to_hex(entry.sha1)); init_tree_desc(&sub, data, size); hit |= grep_tree(opt, paths, &sub, tree_name, down); free(data); } if (hit && opt->status_only) break; } strbuf_release(&pathbuf); return hit; }
static void *load_sha1(const unsigned char *sha1, unsigned long *size, const char *name) { enum object_type type; void *data = lock_and_read_sha1_file(sha1, &type, size); if (!data) error("'%s': unable to read %s", name, sha1_to_hex(sha1)); return data; }
static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, struct tree_desc *tree, struct strbuf *base, int tn_len, int check_attr) { int hit = 0; enum interesting match = entry_not_interesting; struct name_entry entry; int old_baselen = base->len; while (tree_entry(tree, &entry)) { int te_len = tree_entry_len(&entry); if (match != all_entries_interesting) { match = tree_entry_interesting(&entry, base, tn_len, pathspec); if (match == all_entries_not_interesting) break; if (match == entry_not_interesting) continue; } strbuf_add(base, entry.path, te_len); if (S_ISREG(entry.mode)) { hit |= grep_sha1(opt, entry.sha1, base->buf, tn_len, check_attr ? base->buf + tn_len : NULL); } else if (S_ISDIR(entry.mode)) { enum object_type type; struct tree_desc sub; void *data; unsigned long size; data = lock_and_read_sha1_file(entry.sha1, &type, &size); if (!data) die(_("unable to read tree (%s)"), sha1_to_hex(entry.sha1)); strbuf_addch(base, '/'); init_tree_desc(&sub, data, size); hit |= grep_tree(opt, pathspec, &sub, base, tn_len, check_attr); free(data); } strbuf_setlen(base, old_baselen); if (hit && opt->status_only) break; } return hit; }
static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, struct tree_desc *tree, struct strbuf *base, int tn_len) { int hit = 0, matched = 0; struct name_entry entry; int old_baselen = base->len; while (tree_entry(tree, &entry)) { int te_len = tree_entry_len(entry.path, entry.sha1); if (matched != 2) { matched = tree_entry_interesting(&entry, base, tn_len, pathspec); if (matched == -1) break; /* no more matches */ if (!matched) continue; } strbuf_add(base, entry.path, te_len); if (S_ISREG(entry.mode)) { hit |= grep_sha1(opt, entry.sha1, base->buf, tn_len); } else if (S_ISDIR(entry.mode)) { enum object_type type; struct tree_desc sub; void *data; unsigned long size; data = lock_and_read_sha1_file(entry.sha1, &type, &size); if (!data) die("unable to read tree (%s)", sha1_to_hex(entry.sha1)); strbuf_addch(base, '/'); init_tree_desc(&sub, data, size); hit |= grep_tree(opt, pathspec, &sub, base, tn_len); free(data); } strbuf_setlen(base, old_baselen); if (hit && opt->status_only) break; } return hit; }
static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, struct tree_desc *tree, struct strbuf *base, int tn_len, int check_attr) { int hit = 0; enum interesting match = entry_not_interesting; struct name_entry entry; int old_baselen = base->len; struct strbuf name = STRBUF_INIT; int name_base_len = 0; if (super_prefix) { strbuf_addstr(&name, super_prefix); name_base_len = name.len; } while (tree_entry(tree, &entry)) { int te_len = tree_entry_len(&entry); if (match != all_entries_interesting) { strbuf_addstr(&name, base->buf + tn_len); match = tree_entry_interesting(&entry, &name, 0, pathspec); strbuf_setlen(&name, name_base_len); if (match == all_entries_not_interesting) break; if (match == entry_not_interesting) continue; } strbuf_add(base, entry.path, te_len); if (S_ISREG(entry.mode)) { hit |= grep_sha1(opt, entry.oid->hash, base->buf, tn_len, check_attr ? base->buf + tn_len : NULL); } else if (S_ISDIR(entry.mode)) { enum object_type type; struct tree_desc sub; void *data; unsigned long size; data = lock_and_read_sha1_file(entry.oid->hash, &type, &size); if (!data) die(_("unable to read tree (%s)"), oid_to_hex(entry.oid)); strbuf_addch(base, '/'); init_tree_desc(&sub, data, size); hit |= grep_tree(opt, pathspec, &sub, base, tn_len, check_attr); free(data); } else if (recurse_submodules && S_ISGITLINK(entry.mode)) { hit |= grep_submodule(opt, entry.oid->hash, base->buf, base->buf + tn_len); } strbuf_setlen(base, old_baselen); if (hit && opt->status_only) break; } strbuf_release(&name); return hit; }