static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec, struct object *obj, const char *name, const char *path) { if (obj->type == OBJ_BLOB) return grep_oid(opt, &obj->oid, name, 0, path); if (obj->type == OBJ_COMMIT || obj->type == OBJ_TREE) { struct tree_desc tree; void *data; unsigned long size; struct strbuf base; int hit, len; grep_read_lock(); data = read_object_with_reference(&obj->oid, tree_type, &size, NULL); grep_read_unlock(); if (!data) die(_("unable to read tree (%s)"), oid_to_hex(&obj->oid)); len = name ? strlen(name) : 0; strbuf_init(&base, PATH_MAX + len + 1); if (len) { strbuf_add(&base, name, len); strbuf_addch(&base, ':'); } init_tree_desc(&tree, data, size); hit = grep_tree(opt, pathspec, &tree, &base, base.len, obj->type == OBJ_COMMIT, the_repository); strbuf_release(&base); free(data); return hit; } die(_("unable to grep from object of type %s"), type_name(obj->type)); }
static int grep_cache(struct grep_opt *opt, struct repository *repo, const struct pathspec *pathspec, int cached) { int hit = 0; int nr; struct strbuf name = STRBUF_INIT; int name_base_len = 0; if (repo->submodule_prefix) { name_base_len = strlen(repo->submodule_prefix); strbuf_addstr(&name, repo->submodule_prefix); } if (repo_read_index(repo) < 0) die(_("index file corrupt")); for (nr = 0; nr < repo->index->cache_nr; nr++) { const struct cache_entry *ce = repo->index->cache[nr]; strbuf_setlen(&name, name_base_len); strbuf_addstr(&name, ce->name); if (S_ISREG(ce->ce_mode) && match_pathspec(repo->index, pathspec, name.buf, name.len, 0, NULL, S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode))) { /* * If CE_VALID is on, we assume worktree file and its * cache entry are identical, even if worktree file has * been modified, so use cache version instead */ if (cached || (ce->ce_flags & CE_VALID) || ce_skip_worktree(ce)) { if (ce_stage(ce) || ce_intent_to_add(ce)) continue; hit |= grep_oid(opt, &ce->oid, name.buf, 0, name.buf); } else { hit |= grep_file(opt, name.buf); } } else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) && submodule_path_match(repo->index, pathspec, name.buf, NULL)) { hit |= grep_submodule(opt, repo, pathspec, NULL, ce->name, ce->name); } else { continue; } if (ce_stage(ce)) { do { nr++; } while (nr < repo->index->cache_nr && !strcmp(ce->name, repo->index->cache[nr]->name)); nr--; /* compensate for loop control */ } if (hit && opt->status_only) break; } strbuf_release(&name); 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, struct repository *repo) { 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 (repo->submodule_prefix) { strbuf_addstr(&name, repo->submodule_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_oid(opt, entry.oid, 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_oid_file(entry.oid, &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, repo); free(data); } else if (recurse_submodules && S_ISGITLINK(entry.mode)) { hit |= grep_submodule(opt, repo, pathspec, entry.oid, base->buf, base->buf + tn_len); } strbuf_setlen(base, old_baselen); if (hit && opt->status_only) break; } strbuf_release(&name); return hit; }