Skip to content

Commit da314af

Browse files
committed
multifile grep: perform greps in series
Passing a very long argument list to git-grep can cause it to fail; indeed, it's possible for the list of paths passed by git-secrets to either grep or git-grep to exceed the maximum number of arguments allowed in a user's environment (`getconf ARG_MAX`). Instead, let xargs check that the number of arguments won't exceed the system limit. Signed-off-by: Emily Shaffer <[email protected]>
1 parent 8ead034 commit da314af

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

git-secrets

+45-2
Original file line numberDiff line numberDiff line change
@@ -111,18 +111,61 @@ scan_history() {
111111
git_grep() {
112112
local options="$1"; shift
113113
local files=("${@}") combined_patterns=$(load_combined_patterns)
114+
local status=0
114115

115116
[ -z "${combined_patterns}" ] && return 1
116-
GREP_OPTIONS= LC_ALL=C git grep -nwHEI ${options} "${combined_patterns}" -- "${files[@]}"
117+
118+
if [ ${#files[@]} -eq 0 ]; then
119+
GREP_OPTIONS= LC_ALL=C git grep -nwHEI ${options} "${combined_patterns}"
120+
return $?
121+
fi
122+
123+
# let xargs watch for system limit on arg count for us
124+
printf "%s\n" "${files[@]}" |
125+
GREP_OPTIONS= LC_ALL=C xargs -d'\n' sh -c \
126+
'git grep "$@"; rc=$?; if [ $rc -eq 1 ]; then exit 0; else exit 1; fi' - \
127+
-nwHEI "${options}" "${combined_patterns}" --
128+
status=$?
129+
130+
# xargs returns 0 if all invocations returned 0, and we inverted the output
131+
if [ $status -eq 0 ]; then
132+
return 1
133+
else
134+
return 0
135+
fi
117136
}
118137

119138
# Performs a regular grep, taking into account patterns and recursion.
120139
# Note: this function returns 1 on success, 0 on error.
121140
regular_grep() {
122141
local files=("${@}") patterns=$(load_patterns) action='skip'
142+
local status=0
123143
[ -z "${patterns}" ] && return 1
124144
[ ${RECURSIVE} -eq 1 ] && action="recurse"
125-
GREP_OPTIONS= LC_ALL=C grep -d "${action}" -nwHEI "${patterns}" "${files[@]}"
145+
146+
if [ "${files[@]}" = "-" ]; then
147+
GREP_OPTIONS= LC_ALL=C grep -d "${action}" -nwHEI "${patterns}" -
148+
return $?
149+
fi
150+
151+
# let xargs watch for system limit on arg count for us
152+
printf "%s\n" "${files[@]}" |
153+
GREP_OPTIONS= LC_ALL=C xargs -d'\n' sh -c \
154+
'grep "$@"; rc=$?; if [ $rc -eq 2 ]; then exit 255; elif [ $rc -eq 1 ]; \
155+
then exit 0; else exit 1; fi' - \
156+
-d "${action}" -nwHEI "${patterns}"
157+
status=$?
158+
159+
# xargs returns 0 if all invocations returned 0, and we inverted the output
160+
if [ $status -eq 0 ]; then
161+
return 1
162+
# we fudged the output of grep to return 255 on error instead of 2; xargs
163+
# reports a 255 as 124
164+
elif [ $status -eq 124 ]; then
165+
return 2
166+
else
167+
return 0
168+
fi
126169
}
127170

128171
# Process the given status ($1) and output variables ($2).

0 commit comments

Comments
 (0)