Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | #!/usr/bin/env bash |
2 | ||
3 | set -e | |
4 | ||
5 | # List ignored files of current directory by constructing a "find" | |
6 | # expression that matches names of ignored files. | |
7 | # | |
8 | # This script supports a reasonable subset of "gitignore(5)" | |
9 | # semantics. Notably, it does support: | |
10 | # * Patterns read from .gitignore files in current and parent directories | |
11 | # * Blank line separators | |
12 | # * Leading "#" comments | |
13 | # * Trailing "/" directory patterns | |
14 | # * Leading "/" this-directory patterns | |
15 | # and it does not support: | |
16 | # * Patterns read from $GIT_DIR/info/exclude | |
17 | # (b/c inappropriate for a source release) | |
18 | # * Patterns read from file specified by configuration variable core.excludesfile | |
19 | # (b/c inappropriate for a source release) | |
20 | # * Leading "!" negation patterns | |
21 | # (b/c complex semantics) | |
22 | # * Internal "/" FNM_PATHNAME patterns | |
23 | # (b/c complex semantics incompatible with '-path' primary) | |
24 | ||
25 | name=$(basename "$0") | |
26 | dir=$(dirname "$0") | |
27 | root=$(cd "$dir/.." && pwd) | |
28 | ||
29 | ignore='.gitignore' | |
30 | ||
31 | declare -a fargs | |
32 | fargs+=("(") | |
33 | fargs+=("-exec") | |
34 | fargs+=("false") | |
35 | fargs+=(";") | |
36 | idir="." | |
37 | while true; do | |
38 | if [ -r "$idir/$ignore" ]; then | |
39 | while IFS= read -r opat; do | |
40 | pat="$opat" | |
41 | ## Blank line: Separator -- supported | |
42 | if [ -z "$pat" ]; then | |
43 | continue | |
44 | fi | |
45 | ## Leading "#": Comment -- supported | |
46 | if [ "${pat:0:1}" = "#" ]; then | |
47 | continue | |
48 | fi | |
49 | ## Leading "\#": Pattern beginning with "#" -- supported | |
50 | if [ "${pat:0:2}" = "\#" ]; then | |
51 | pat="#${pat:2}" | |
52 | fi | |
53 | ## Leading "!": Negated pattern -- unsupported | |
54 | if [ "${pat:0:1}" = "!" ]; then | |
55 | echo "$name:: unsupported pattern: $opat" | |
56 | exit 1 | |
57 | fi | |
58 | ## Leading "\!": Pattern beginning with "!" -- supported | |
59 | if [ "${pat:0:2}" = "\!" ]; then | |
60 | pat="!${pat:2}" | |
61 | fi | |
62 | ## Trailing "/": Directory pattern -- supported | |
63 | if [ "${pat:$((${#pat}-1)):1}" = "/" ]; then | |
64 | dirPat="yes" | |
65 | pat="${pat:0:$((${#pat}-1))}" | |
66 | else | |
67 | dirPat="no" | |
68 | fi | |
69 | ## Leading "/": This-directory pattern -- supported | |
70 | if [ "${pat:0:1}" = "/" ]; then | |
71 | if [ "$idir" = "." ]; then | |
72 | pat="${pat:1}" | |
73 | else | |
74 | continue | |
75 | fi | |
76 | fi | |
77 | ## Internal "/": FNM_PATHNAME pattern -- unsupported | |
78 | if [ -z "${pat##*/*}" ]; then | |
79 | echo "$name:: unsupported pattern: $opat" | |
80 | exit 1 | |
81 | fi | |
82 | fargs+=("-o") | |
83 | fargs+=("(") | |
84 | if [ "$dirPat" = "yes" ]; then | |
85 | fargs+=("-type") | |
86 | fargs+=("d") | |
87 | fi | |
88 | fargs+=("-name") | |
89 | fargs+=("$pat") | |
90 | fargs+=(")") | |
91 | done < "$idir/$ignore" | |
92 | fi | |
93 | if [ "$(cd "$idir" && pwd)" != "$root" ]; then | |
94 | idir="../$idir" | |
95 | else | |
96 | break | |
97 | fi | |
98 | done | |
99 | fargs+=(")") | |
100 | ||
101 | find . -mindepth 1 -maxdepth 1 "${fargs[@]}" -print |