#!/bin/bash # List files which exist in the working tree and are ignored by this # repository's own rules: any .gitignore file, plus $GIT_DIR/info/exclude. # # Unlike `git status --ignored`, the global core.excludesfile is not consulted # unless --global is given, so the output only contains paths this repository # chose to ignore. # # Works inside a linked worktree, where .git is a file and info/exclude lives in # the common git directory rather than next to the worktree. # # Usage: git-ls-ignored [] [--] [...] # # -d, --directory list an ignored directory by name instead of its contents # -g, --global also apply the global core.excludesfile # -z terminate entries with NUL instead of newline # -h, --help show this message # # Paths are relative to the top of the working tree. Without a the # whole working tree is listed, not just the current directory. # Print the comment block above, minus the shebang, as the help text. usage() { awk 'NR == 1 { next } /^#/ { sub(/^# ?/, ""); print; next } { exit }' "$0" } global=false options=() paths=() while [ $# -gt 0 ]; do case "$1" in -d | --directory) options+=(--directory) ;; -g | --global) global=true ;; -z) options+=(-z) ;; -h | --help) usage exit 0 ;; --) shift paths+=("$@") break ;; -*) echo "error: unknown option: $1" >&2 usage >&2 exit 1 ;; *) paths+=("$1") ;; esac shift done # In a worktree .git is a file pointing at .git/worktrees/, which has no # info/exclude of its own; Git reads the one in the common directory, so that is # the file to point --exclude-from at. The common directory is reported relative # to the current directory unless it happens to be absolute. common_dir=$(git rev-parse --git-common-dir) || exit $? case "$common_dir" in /*) ;; *) common_dir="$PWD/$common_dir" ;; esac if $global; then # .gitignore, info/exclude and core.excludesfile. excludes=(--exclude-standard) else excludes=(--exclude-per-directory=.gitignore) # --exclude-from is fatal on a missing file, and info/exclude is optional. if [ -f "$common_dir/info/exclude" ]; then excludes+=("--exclude-from=$common_dir/info/exclude") fi fi git ls-files --others --ignored --full-name "${excludes[@]}" "${options[@]}" \ -- "${paths[@]:-:/}"