static inline int prune_traversal(struct name_entry *e, struct traverse_info *info, struct strbuf *base, int still_interesting) { if (!info->pathspec || still_interesting == 2) return 2; if (still_interesting < 0) return still_interesting; return tree_entry_interesting(e, base, 0, info->pathspec); }
static void skip_uninteresting(struct tree_desc *t, struct strbuf *base, struct diff_options *opt, int *match) { while (t->size) { *match = tree_entry_interesting(&t->entry, base, 0, &opt->pathspec); if (*match) { if (*match < 0) t->size = 0; break; } update_tree_entry(t); } }
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 void skip_uninteresting(struct tree_desc *t, struct strbuf *base, struct diff_options *opt) { enum interesting match; while (t->size) { match = tree_entry_interesting(&t->entry, base, 0, &opt->pathspec); if (match) { if (match == all_entries_not_interesting) t->size = 0; break; } update_tree_entry(t); } }
/* A whole sub-tree went away or appeared */ static void show_tree(struct diff_options *opt, const char *prefix, struct tree_desc *desc, struct strbuf *base) { int match = 0; for (; desc->size; update_tree_entry(desc)) { if (match != 2) { match = tree_entry_interesting(&desc->entry, base, 0, &opt->pathspec); if (match < 0) break; if (match == 0) continue; } show_entry(opt, prefix, desc, base); } }
/* A whole sub-tree went away or appeared */ static void show_tree(struct diff_options *opt, const char *prefix, struct tree_desc *desc, struct strbuf *base) { enum interesting match = entry_not_interesting; for (; desc->size; update_tree_entry(desc)) { if (match != all_entries_interesting) { match = tree_entry_interesting(&desc->entry, base, 0, &opt->pathspec); if (match == all_entries_not_interesting) break; if (match == entry_not_interesting) continue; } show_entry(opt, prefix, desc, base); } }
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; }
/* A whole sub-tree went away or appeared */ static void show_tree(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base, int baselen) { int all_interesting = 0; while (desc->size) { int show; if (all_interesting) show = 1; else { show = tree_entry_interesting(desc, base, baselen, opt); if (show == 2) all_interesting = 1; } if (show < 0) break; if (show) show_entry(opt, prefix, desc, base, baselen); update_tree_entry(desc); } }
static void skip_uninteresting(struct tree_desc *t, const char *base, int baselen, struct diff_options *opt) { int all_interesting = 0; while (t->size) { int show; if (all_interesting) show = 1; else { show = tree_entry_interesting(t, base, baselen, opt); if (show == 2) all_interesting = 1; } if (!show) { update_tree_entry(t); continue; } /* Skip it all? */ if (show < 0) t->size = 0; return; } }
static void process_tree(struct rev_info *revs, struct tree *tree, show_object_fn show, struct name_path *path, struct strbuf *base, const char *name) { struct object *obj = &tree->object; struct tree_desc desc; struct name_entry entry; struct name_path me; int all_interesting = (revs->diffopt.pathspec.nr == 0); int baselen = base->len; if (!revs->tree_objects) return; if (!obj) die("bad tree object"); if (obj->flags & (UNINTERESTING | SEEN)) return; if (parse_tree(tree) < 0) die("bad tree object %s", sha1_to_hex(obj->sha1)); obj->flags |= SEEN; show(obj, path, name); me.up = path; me.elem = name; me.elem_len = strlen(name); if (!all_interesting) { strbuf_addstr(base, name); if (base->len) strbuf_addch(base, '/'); } init_tree_desc(&desc, tree->buffer, tree->size); while (tree_entry(&desc, &entry)) { if (!all_interesting) { int showit = tree_entry_interesting(&entry, base, 0, &revs->diffopt.pathspec); if (showit < 0) break; else if (!showit) continue; else if (showit == 2) all_interesting = 1; } if (S_ISDIR(entry.mode)) process_tree(revs, lookup_tree(entry.sha1), show, &me, base, entry.path); else if (S_ISGITLINK(entry.mode)) process_gitlink(revs, entry.sha1, show, &me, entry.path); else process_blob(revs, lookup_blob(entry.sha1), show, &me, entry.path); } strbuf_setlen(base, baselen); free(tree->buffer); tree->buffer = NULL; }
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; }
static void process_tree(struct rev_info *revs, struct tree *tree, show_object_fn show, struct strbuf *base, const char *name, void *cb_data) { struct object *obj = &tree->object; struct tree_desc desc; struct name_entry entry; enum interesting match = revs->diffopt.pathspec.nr == 0 ? all_entries_interesting: entry_not_interesting; int baselen = base->len; if (!revs->tree_objects) return; if (!obj) die("bad tree object"); if (obj->flags & (UNINTERESTING | SEEN)) return; if (parse_tree_gently(tree, revs->ignore_missing_links) < 0) { if (revs->ignore_missing_links) return; die("bad tree object %s", oid_to_hex(&obj->oid)); } obj->flags |= SEEN; strbuf_addstr(base, name); show(obj, base->buf, cb_data); if (base->len) strbuf_addch(base, '/'); init_tree_desc(&desc, tree->buffer, tree->size); while (tree_entry(&desc, &entry)) { if (match != all_entries_interesting) { match = tree_entry_interesting(&entry, base, 0, &revs->diffopt.pathspec); if (match == all_entries_not_interesting) break; if (match == entry_not_interesting) continue; } if (S_ISDIR(entry.mode)) process_tree(revs, lookup_tree(entry.sha1), show, base, entry.path, cb_data); else if (S_ISGITLINK(entry.mode)) process_gitlink(revs, entry.sha1, show, base, entry.path, cb_data); else process_blob(revs, lookup_blob(entry.sha1), show, base, entry.path, cb_data); } strbuf_setlen(base, baselen); free_tree_buffer(tree); }
static int read_tree_1(struct tree *tree, struct strbuf *base, int stage, const struct pathspec *pathspec, read_tree_fn_t fn, void *context) { struct tree_desc desc; struct name_entry entry; unsigned char sha1[20]; int len, oldlen = base->len; enum interesting retval = entry_not_interesting; if (parse_tree(tree)) return -1; init_tree_desc(&desc, tree->buffer, tree->size); while (tree_entry(&desc, &entry)) { if (retval != all_entries_interesting) { retval = tree_entry_interesting(&entry, base, 0, pathspec); if (retval == all_entries_not_interesting) break; if (retval == entry_not_interesting) continue; } switch (fn(entry.sha1, base, entry.path, entry.mode, stage, context)) { case 0: continue; case READ_TREE_RECURSIVE: break; default: return -1; } if (S_ISDIR(entry.mode)) hashcpy(sha1, entry.sha1); else if (S_ISGITLINK(entry.mode)) { struct commit *commit; commit = lookup_commit(entry.sha1); if (!commit) die("Commit %s in submodule path %s%s not found", sha1_to_hex(entry.sha1), base->buf, entry.path); if (parse_commit(commit)) die("Invalid commit %s in submodule path %s%s", sha1_to_hex(entry.sha1), base->buf, entry.path); hashcpy(sha1, commit->tree->object.sha1); } else continue; len = tree_entry_len(&entry); strbuf_add(base, entry.path, len); strbuf_addch(base, '/'); retval = read_tree_1(lookup_tree(sha1), base, stage, pathspec, fn, context); strbuf_setlen(base, oldlen); if (retval) return -1; } return 0; }