When :(attr) was added, it supported one of the two main pathspec matching functions, the one that works on a list of paths. The other one works on a tree, tree_entry_interesting(), which gets :(attr) support in this series. With this, "git grep <pattern> <tree> -- :(attr)" or "git log :(attr)" will not abort with BUG() anymore. But this also reveals an interesting thing: even though we walk on a tree, we check attributes from _worktree_ (and optionally fall back to the index). This is how attributes are implemented since forever. I think this is not a big deal if we communicate clearly with the user. But otherwise, this series can be scraped, as reading attributes from a specific tree could be a lot of work. The main patch is the last one. The others are just to open a path to pass "struct index_state *" down to tree_entry_interesting(). This may become standard procedure because we don't want to stick the_index (or the_repository) here and there. Nguyễn Thái Ngọc Duy (5): tree.c: make read_tree*() take 'struct repository *' tree-walk.c: make tree_entry_interesting() take an index pathspec.h: clean up "extern" in function declarations dir.c: move, rename and export match_attrs() tree-walk: support :(attr) matching Documentation/glossary-content.txt | 2 + archive.c | 6 +- builtin/checkout.c | 3 +- builtin/grep.c | 3 +- builtin/log.c | 5 +- builtin/ls-files.c | 2 +- builtin/ls-tree.c | 3 +- builtin/merge-tree.c | 2 +- dir.c | 41 +------------- list-objects.c | 3 +- merge-recursive.c | 3 +- pathspec.c | 38 +++++++++++++ pathspec.h | 27 +++++---- revision.c | 1 + t/t6135-pathspec-with-attrs.sh | 58 ++++++++++++++++++- tree-diff.c | 3 +- tree-walk.c | 89 ++++++++++++++++++++++-------- tree-walk.h | 10 ++-- tree.c | 21 ++++--- tree.h | 18 +++--- unpack-trees.c | 6 +- 21 files changed, 235 insertions(+), 109 deletions(-) -- 2.19.1.1327.g328c130451.dirty