Protect scripted Porcelains from GREP_OPTIONS insanity

If the user has exported the GREP_OPTIONS environment variable, the output
from "grep" and "egrep" in scripted Porcelains may be different from what
they expect.  For example, we may want to count number of matching lines,
by "grep" piped to "wc -l", and GREP_OPTIONS=-C3 will break such use.

The approach taken by this change to address this issue is to protect only
our own use of grep/egrep.  Because we do not unset it at the beginning of
our scripts, hook scripts run from the scripted Porcelains are exposed to
the same insanity this environment variable causes when grep/egrep is used
to implement logic (e.g. "grep | wc -l"), and it is entirely up to the
hook scripts to protect themselves.

On the other hand, applypatch-msg hook may want to show offending words in
the proposed commit log message using grep to the end user, and the user
might want to set GREP_OPTIONS=--color to paint the match more visibly.
The approach to protect only our own use without unsetting the environment
variable globally will allow this use case.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Junio C Hamano 2009-11-23 15:56:32 -08:00
parent 7b1042292d
commit e1622bfcba
8 changed files with 26 additions and 18 deletions

View File

@ -205,7 +205,7 @@ check_patch_format () {
# and see if it looks like that they all begin with the # and see if it looks like that they all begin with the
# header field names... # header field names...
sed -n -e '/^$/q' -e '/^[ ]/d' -e p "$1" | sed -n -e '/^$/q' -e '/^[ ]/d' -e p "$1" |
LC_ALL=C egrep -v '^[!-9;-~]+:' >/dev/null || sane_egrep -v '^[!-9;-~]+:' >/dev/null ||
patch_format=mbox patch_format=mbox
fi fi
} < "$1" || clean_abort } < "$1" || clean_abort
@ -554,7 +554,7 @@ do
stop_here $this stop_here $this
# skip pine's internal folder data # skip pine's internal folder data
grep '^Author: Mail System Internal Data$' \ sane_grep '^Author: Mail System Internal Data$' \
<"$dotest"/info >/dev/null && <"$dotest"/info >/dev/null &&
go_next && continue go_next && continue

View File

@ -393,7 +393,7 @@ bisect_run () {
cat "$GIT_DIR/BISECT_RUN" cat "$GIT_DIR/BISECT_RUN"
if grep "first bad commit could be any of" "$GIT_DIR/BISECT_RUN" \ if sane_grep "first bad commit could be any of" "$GIT_DIR/BISECT_RUN" \
> /dev/null; then > /dev/null; then
echo >&2 "bisect run cannot continue any more" echo >&2 "bisect run cannot continue any more"
exit $res exit $res
@ -405,7 +405,7 @@ bisect_run () {
exit $res exit $res
fi fi
if grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null; then if sane_grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null; then
echo "bisect run success" echo "bisect run success"
exit 0; exit 0;
fi fi

View File

@ -457,7 +457,7 @@ if [ "$filter_tag_name" ]; then
git mktag) || git mktag) ||
die "Could not create new tag object for $ref" die "Could not create new tag object for $ref"
if git cat-file tag "$ref" | \ if git cat-file tag "$ref" | \
grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1 sane_grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1
then then
warn "gpg signature stripped from tag object $sha1t" warn "gpg signature stripped from tag object $sha1t"
fi fi

View File

@ -41,7 +41,7 @@ resolve_full_httpd () {
case "$httpd" in case "$httpd" in
*apache2*|*lighttpd*) *apache2*|*lighttpd*)
# ensure that the apache2/lighttpd command ends with "-f" # ensure that the apache2/lighttpd command ends with "-f"
if ! echo "$httpd" | grep -- '-f *$' >/dev/null 2>&1 if ! echo "$httpd" | sane_grep -- '-f *$' >/dev/null 2>&1
then then
httpd="$httpd -f" httpd="$httpd -f"
fi fi
@ -297,8 +297,8 @@ EOF
# check to see if Dennis Stosberg's mod_perl compatibility patch # check to see if Dennis Stosberg's mod_perl compatibility patch
# (<20060621130708.Gcbc6e5c@leonov.stosberg.net>) has been applied # (<20060621130708.Gcbc6e5c@leonov.stosberg.net>) has been applied
if test -f "$module_path/mod_perl.so" && grep 'MOD_PERL' \ if test -f "$module_path/mod_perl.so" &&
"$GIT_DIR/gitweb/gitweb.cgi" >/dev/null sane_grep 'MOD_PERL' "$GIT_DIR/gitweb/gitweb.cgi" >/dev/null
then then
# favor mod_perl if available # favor mod_perl if available
cat >> "$conf" <<EOF cat >> "$conf" <<EOF
@ -316,7 +316,7 @@ EOF
# plain-old CGI # plain-old CGI
resolve_full_httpd resolve_full_httpd
list_mods=$(echo "$full_httpd" | sed "s/-f$/-l/") list_mods=$(echo "$full_httpd" | sed "s/-f$/-l/")
$list_mods | grep 'mod_cgi\.c' >/dev/null 2>&1 || \ $list_mods | sane_grep 'mod_cgi\.c' >/dev/null 2>&1 || \
echo "LoadModule cgi_module $module_path/mod_cgi.so" >> "$conf" echo "LoadModule cgi_module $module_path/mod_cgi.so" >> "$conf"
cat >> "$conf" <<EOF cat >> "$conf" <<EOF
AddHandler cgi-script .cgi AddHandler cgi-script .cgi

View File

@ -106,8 +106,8 @@ mark_action_done () {
sed -e 1q < "$TODO" >> "$DONE" sed -e 1q < "$TODO" >> "$DONE"
sed -e 1d < "$TODO" >> "$TODO".new sed -e 1d < "$TODO" >> "$TODO".new
mv -f "$TODO".new "$TODO" mv -f "$TODO".new "$TODO"
count=$(grep -c '^[^#]' < "$DONE") count=$(sane_grep -c '^[^#]' < "$DONE")
total=$(($count+$(grep -c '^[^#]' < "$TODO"))) total=$(($count+$(sane_grep -c '^[^#]' < "$TODO")))
if test "$last_count" != "$count" if test "$last_count" != "$count"
then then
last_count=$count last_count=$count
@ -147,7 +147,7 @@ die_abort () {
} }
has_action () { has_action () {
grep '^[^#]' "$1" >/dev/null sane_grep '^[^#]' "$1" >/dev/null
} }
pick_one () { pick_one () {
@ -731,7 +731,7 @@ first and then run 'git rebase --continue' again."
git rev-list $REVISIONS | git rev-list $REVISIONS |
while read rev while read rev
do do
if test -f "$REWRITTEN"/$rev -a "$(grep "$rev" "$DOTEST"/not-cherry-picks)" = "" if test -f "$REWRITTEN"/$rev -a "$(sane_grep "$rev" "$DOTEST"/not-cherry-picks)" = ""
then then
# Use -f2 because if rev-list is telling us this commit is # Use -f2 because if rev-list is telling us this commit is
# not worthwhile, we don't want to track its multiple heads, # not worthwhile, we don't want to track its multiple heads,
@ -739,7 +739,7 @@ first and then run 'git rebase --continue' again."
# be rebasing on top of it # be rebasing on top of it
git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$DROPPED"/$rev git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$DROPPED"/$rev
short=$(git rev-list -1 --abbrev-commit --abbrev=7 $rev) short=$(git rev-list -1 --abbrev-commit --abbrev=7 $rev)
grep -v "^[a-z][a-z]* $short" <"$TODO" > "${TODO}2" ; mv "${TODO}2" "$TODO" sane_grep -v "^[a-z][a-z]* $short" <"$TODO" > "${TODO}2" ; mv "${TODO}2" "$TODO"
rm "$REWRITTEN"/$rev rm "$REWRITTEN"/$rev
fi fi
done done

View File

@ -467,7 +467,7 @@ orig_head=$branch
mb=$(git merge-base "$onto" "$branch") mb=$(git merge-base "$onto" "$branch")
if test "$upstream" = "$onto" && test "$mb" = "$onto" && if test "$upstream" = "$onto" && test "$mb" = "$onto" &&
# linear history? # linear history?
! (git rev-list --parents "$onto".."$branch" | grep " .* ") > /dev/null ! (git rev-list --parents "$onto".."$branch" | sane_grep " .* ") > /dev/null
then then
if test -z "$force_rebase" if test -z "$force_rebase"
then then

View File

@ -114,6 +114,14 @@ git_editor() {
eval "${GIT_EDITOR:=vi}" '"$@"' eval "${GIT_EDITOR:=vi}" '"$@"'
} }
sane_grep () {
GREP_OPTIONS= LC_ALL=C grep "$@"
}
sane_egrep () {
GREP_OPTIONS= LC_ALL=C egrep "$@"
}
is_bare_repository () { is_bare_repository () {
git rev-parse --is-bare-repository git rev-parse --is-bare-repository
} }

View File

@ -57,7 +57,7 @@ resolve_relative_url ()
# #
module_list() module_list()
{ {
git ls-files --error-unmatch --stage -- "$@" | grep '^160000 ' git ls-files --error-unmatch --stage -- "$@" | sane_grep '^160000 '
} }
# #
@ -567,7 +567,7 @@ cmd_summary() {
cd_to_toplevel cd_to_toplevel
# Get modified modules cared by user # Get modified modules cared by user
modules=$(git $diff_cmd $cached --raw $head -- "$@" | modules=$(git $diff_cmd $cached --raw $head -- "$@" |
egrep '^:([0-7]* )?160000' | sane_egrep '^:([0-7]* )?160000' |
while read mod_src mod_dst sha1_src sha1_dst status name while read mod_src mod_dst sha1_src sha1_dst status name
do do
# Always show modules deleted or type-changed (blob<->module) # Always show modules deleted or type-changed (blob<->module)
@ -581,7 +581,7 @@ cmd_summary() {
test -z "$modules" && return test -z "$modules" && return
git $diff_cmd $cached --raw $head -- $modules | git $diff_cmd $cached --raw $head -- $modules |
egrep '^:([0-7]* )?160000' | sane_egrep '^:([0-7]* )?160000' |
cut -c2- | cut -c2- |
while read mod_src mod_dst sha1_src sha1_dst status name while read mod_src mod_dst sha1_src sha1_dst status name
do do