Meaning you used Apple's version of git before?
$ echo abd > test.file
$ /usr/bin/git grep --untracked 'b\|c' test.file
test.file:abd
$ /usr/bin/git version
git version 2.37.1 (Apple Git-137.1)
$ git grep --untracked 'b\|c' test.file
$ git version
git version 2.39.0
So I can reproduce your findings on macOS Ventura. Same with grep:
$ grep 'b\|c' test.file
abd
$ grep --version
grep (BSD grep, GNU compatible) 2.6.0-FreeBSD
re_format(7) says:
"Obsolete (“basic”) regular expressions differ in several respects.
‘|’ is an ordinary character and there is no equivalent for its
functionality.".Under the headline "ENHANCED FEATURES" it continues, however:
"When the REG_ENHANCED flag is passed to one of the regcomp()
variants, additional features are activated."And:
"For enhanced basic REs, ‘+’, ‘?’ and ‘|’ remain regular characters,
but ‘\+’, ‘\?’ and ‘\|’ have the same special meaning as the
unescaped characters do for extended REs, i.e., one or more
matches, zero or one matches and alteration, respectively."So apparently Apple chose a middle ground between basic and extended regular expressions for its grep and git grep.
Under "IMPLEMENTATION CHOICES" it says:
"The regex implementation in Mac OS X 10.8 and later is based on a
heavily modified subset of TRE (http://laurikari.net/tre/)."The manpage of GNU grep says:
"grep understands three different versions of regular expression
syntax: “basic” (BRE), “extended” (ERE) and “perl” (PCRE). In
GNU grep there is no difference in available functionality
between basic and extended syntax. In other implementations,
basic regular expressions are less powerful."And under the headline "Basic vs Extended Regular Expressions":
"In basic regular expressions the meta-characters ?, +, {, |, (,
and ) lose their special meaning; instead use the backslashed
versions \?, \+, \{, \|, \(, and \)."So GNU grep apparently made the same choice as Apple, probably far earlier.
When I compile git with NO_REGEX and thus with the fallback in compat/regex/, the result supports alternation as well:
$ ./git grep --untracked 'b\|c' test.file
test.file:abd
$ nm ./git | grep regcomp
0000000100255978 T _git_regcomp
Based on that I suggest:
--- >8 ---
Subject: grep: use REG_ENHANCED on macOS
GNU grep(1) and regcomp(3) use enhanced basic regular expressions by default, which means that it e.g. supports alternation, e.g. "a\|b" matches both "a" and "b". The same is true for our compat/regex/ implementation.
On macOS Ventura (and possibly earlier) grep(1) also uses enhanced BREs, but regcomp(3) requires the flag REG_ENHANCED to turn them on. Do that for git grep if possible, for consistency with the platform's grep(1) and our fallback library.
It would be simpler to use REG_ENHANCED everywhere it is defined instead of adding a Makefile setting, but it's a non-standard extension and might mean something else on other platforms.
Reported-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
Signed-off-by: René Scharfe <l.s.r@web.de>
---
Makefile | 8 ++++++++
config.mak.uname | 1 +
grep.c | 4 ++++
3 files changed, 13 insertions(+)