简体   繁体   中英

git grep and OR'd multiple clauses with pipe?

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?

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM