-1

I want to search for multiple clauses with grep - and I know that one can use a pipe | to OR the clauses; so here is a test I'm trying on MSYS2, Windows 10:

$ uname -s
MSYS_NT-10.0-18363
$ git --version
git version 2.25.2
$ grep --version | head -1
grep (GNU grep) 3.0

$ git clone https://github.com/xythobuz/avrSerial.git
...
$ cd avrSerial/

$ grep -r 'SERIALDATA\|UART_INTERRUPT_MASK' . --include='*.[ch]'
./serial.c:#define SERIALDATA  0
./serial.c:    rxBuffer[uart][rxWrite[uart]] = *serialRegisters[uart][SERIALDATA];
./serial.c:        *serialRegisters[uart][SERIALDATA] = sendThisNext[uart];
./serial.c:            *serialRegisters[uart][SERIALDATA] = txBuffer[uart][txRead[uart]];
./serial.c:            serialRegisters[uart]->CTRLA &= ~(UART_INTERRUPT_MASK << 2); // TXCINTLVL
./serial_device.h:#define UART_INTERRUPT_MASK 0x03

So, just grep works fine here, with multiple clauses with pipe.

However, I'd like to know in which C functions do the clauses/keyword matches occur, so I try to use git grep with the -p switch:

$ git grep -p 'SERIALDATA\|UART_INTERRUPT_MASK' -- '*.[ch]'
$

... and absolutely nothing is returned, for the same clause.

However, if I repeat this test on Ubuntu:

$ echo `uname -s` `cat /etc/issue | head -1`
Linux Ubuntu 18.04.4 LTS \n \l
$ git --version
git version 2.17.1
$ grep --version | head -1
grep (GNU grep) 3.1

# same procedure with git clone, cd ... grep -r works the same too; but git grep -p is different:

$ git grep -p 'SERIALDATA\|UART_INTERRUPT_MASK' -- '*.[ch]'
serial.c:#define SERIALDATA  0
serial.c=static void serialReceiveInterrupt(uint8_t uart) {
serial.c:    rxBuffer[uart][rxWrite[uart]] = *serialRegisters[uart][SERIALDATA];
serial.c=static void serialTransmitInterrupt(uint8_t uart) {
serial.c:        *serialRegisters[uart][SERIALDATA] = sendThisNext[uart];
serial.c:            *serialRegisters[uart][SERIALDATA] = txBuffer[uart][txRead[uart]];
serial.c:            serialRegisters[uart]->CTRLA &= ~(UART_INTERRUPT_MASK << 2); // TXCINTLVL
serial_device.h=uint8_t const serialBits[UART_COUNT][UART_BITS] = {{
serial_device.h:#define UART_INTERRUPT_MASK 0x03

... here it works?!

Does anyone know why the different behavior in regards to git grep on these systems? Is there a git config setting I have to enable, or is it a regression in git, or maybe there are some shell escaping problems on MSYS2?

Or in general - how can I get the same kind of git grep response on MSYS2, as I get it on Ubuntu?

sdaau
  • 36,975
  • 46
  • 198
  • 278
  • 2
    Git can be built against a system's regular expression library, and when it is, it has only as many capabilities as the system's RE library. That's *probably* the issue here. You might want to grab the Git source and build your own, or look for some alternative build. (I understand building on Windows is painful. I avoid it myself, by avoiding Windows...) – torek May 08 '20 at 21:02
  • Indeed @torek - just checked: on MSYS2, ``$ ntldd `which git` | grep pcre`` returns `msys-pcre2-8-0.dll`, so PCRE 2.8 (?); while on Ubuntu, ``$ ldd `which git` | grep pcre`` returns `libpcre.so.3`, so PCRE 3? Could be that this is the problem ... – sdaau May 08 '20 at 21:11
  • Edit: `pacman -Ss pcre` on the MSYS2 system says it can see both `libpcre 8.44-1` and `libpcre2_8 10.34-1` installed; while `apt-show-versions -r libpcre | grep uptodate` on Ubuntu says it sees `libpcre3 2:8.39-9` installed – sdaau May 08 '20 at 21:21

1 Answers1

-1

I'll post this as an answer - after looking into git help grep, and brute forcing some switches, found that this works on MSYS2:

$ git grep -p --extended-regexp 'UART_INTERRUPT_MASK|SERIALDATA' -- '*.[ch]'
serial.c:#define SERIALDATA  0
serial.c=static void serialReceiveInterrupt(uint8_t uart) {
serial.c:    rxBuffer[uart][rxWrite[uart]] = *serialRegisters[uart][SERIALDATA];
serial.c=static void serialTransmitInterrupt(uint8_t uart) {
serial.c:        *serialRegisters[uart][SERIALDATA] = sendThisNext[uart];
serial.c:            *serialRegisters[uart][SERIALDATA] = txBuffer[uart][txRead[uart]];
serial.c:            serialRegisters[uart]->CTRLA &= ~(UART_INTERRUPT_MASK << 2); // TXCINTLVL
serial_device.h=uint8_t const serialBits[UART_COUNT][UART_BITS] = {{
serial_device.h:#define UART_INTERRUPT_MASK 0x03

and also this:

$ git grep -p --perl-regexp 'UART_INTERRUPT_MASK|SERIALDATA' -- '*.[ch]'
serial.c:#define SERIALDATA  0
serial.c=static void serialReceiveInterrupt(uint8_t uart) {
serial.c:    rxBuffer[uart][rxWrite[uart]] = *serialRegisters[uart][SERIALDATA];
serial.c=static void serialTransmitInterrupt(uint8_t uart) {
serial.c:        *serialRegisters[uart][SERIALDATA] = sendThisNext[uart];
serial.c:            *serialRegisters[uart][SERIALDATA] = txBuffer[uart][txRead[uart]];
serial.c:            serialRegisters[uart]->CTRLA &= ~(UART_INTERRUPT_MASK << 2); // TXCINTLVL
serial_device.h=uint8_t const serialBits[UART_COUNT][UART_BITS] = {{
serial_device.h:#define UART_INTERRUPT_MASK 0x03

So, use either --perl-regexp or --extended-regexp - and do not escape the pipe | with a backslash \, as one needs to do for usual grep.

sdaau
  • 36,975
  • 46
  • 198
  • 278