Have tree hide gitignored files
Tree supports the -I
flag.
-I pattern Do not list those files that match the wild-card pattern.
Tree supports a single pattern which will exclude all files/directories that match it.
Git's ignore files are a bit more complicated:
Exclusion can come from multiple files, $HOME/.config/git/ignore
, the output of git config --get core.excludesfile
, .gitignore
(per directory), ~/.gitignore
, and more (see man gitignore
).
Another problem is the patterns that tree
supports differs from what git does (as noted by @Brad Urani).
But we can get close-ish ...
tree -I "$(grep -hvE '^$|^#' {~/,,$(git rev-parse --show-toplevel)/}.gitignore|sed 's:/$::'|tr \\n '\|')"
Or as a function:
function gtree {
git_ignore_files=("$(git config --get core.excludesfile)" .gitignore ~/.gitignore)
ignore_pattern="$(grep -hvE '^$|^#' "${git_ignore_files[@]}" 2>/dev/null|sed 's:/$::'|tr '\n' '\|')"
if git status &> /dev/null && [[ -n "${ignore_pattern}" ]]; then
tree -I "${ignore_pattern}" "${@}"
else
tree "${@}"
fi
}
This might help: list git
ignored files in an almost-compatible way for tree
filter:
function tree-git-ignore {
# tree respecting gitignore
local ignored=$(git ls-files -ci --others --directory --exclude-standard)
local ignored_filter=$(echo "$ignored" \
| egrep -v "^#.*$|^[[:space:]]*$" \
| sed 's~^/~~' \
| sed 's~/$~~' \
| tr "\\n" "|")
tree --prune -I ".git|${ignored_filter: : -1}" "$@"
}
Another way is possible if you're using tree 1.8.0
since it supports the --fromfile
flag:
--fromfile Reads a directory listing from a file rather than the file-system. Paths provided on the command
line are files to read from rather than directories to search. The dot (.) directory indicates that tree
should read paths from standard input.
We could use git ls-tree
to get all non-git-ignored files in a project, and pipe the output to tree
.
Assuming we have a git repository, where ignored
files are ignored in .gitignore
:
git_repo
├── .gitignore
├── bar
│ ├── b.txt
│ └── ignored
├── foo
│ ├── a.txt
│ └── ignored
└── ignored
The following command:
git ls-tree -r --name-only HEAD | tree --fromfile
Gives:
.
├── .gitignore
├── bar
│ └── b.txt
└── foo
└── a.txt
2 directories, 3 files
Or if you need a specific path:
git ls-tree -r --name-only HEAD foo | tree --fromfile
Gives:
.
└── a.txt
0 directories, 1 file
Caveats
- Beware that changes such as deleted or renamed files that haven't already been committed can cause
git ls-tree
to appear out of sync.