0

I can't make a positive lookahead based regex to work in git grep and/or git log -L. I'm using git log -L <funcname>:<filename> feature using a regex <funcname>. The test file is the following one :

public class FakeFile {
    public static void main(String[] args) {
        System.out.println('Hello World');
    }
    public static void method2() {
        System.out.println('method2');
    }
    public static void method2(float i) {
        System.out.println(String.format('method2 %f', i));
    }
    public static void method3() {
        System.out.println('method3');
    }
}

and following this answer, I'm using ^(?=.*float i).*method2.*$ to match the line where method2 is defined with a float argument. It works on rubular, but I can't make it work in my shell using either grep or git log -L. I've tried to surround it with ' and \ characters, without success.

Any idea ?

EDIT : add a missing .* is the regex.

torek
  • 448,244
  • 59
  • 642
  • 775
Kahsius
  • 747
  • 2
  • 7
  • 18
  • 1
    In the rubular demo you use `^(?=.*float i).*method2.*$` which is not the same as `^(?=float i).*method2.*$` Did you try `grep -oP` if that is supported? – The fourth bird Oct 25 '21 at 08:57
  • Right, again, you can't expect arguments to be declared before the method name, so you still do not need a lookaround, `^.*method2.*float i.*` would do. – Wiktor Stribiżew Oct 25 '21 at 09:02
  • @WiktorStribiżew I need a way to match argument in any order, that's why I was considering positive lookahead. You're right, I've made a typo in the message, I'm changing it to include `.*` in the lookahead. – Kahsius Oct 25 '21 at 09:06
  • @Thefourthbird I can't rely on grep parameters since I need the regex to work with `git log -L` command, but thanks for the comment ! – Kahsius Oct 25 '21 at 09:06
  • 1
    At any rate, POSIX regex does not support lookarounds. You can't use them here. If you can use `-P` to enable PCRE engine, only then you can use lookarounds. – Wiktor Stribiżew Oct 25 '21 at 09:14
  • @Thefourthbird, I'll definitely try to used the alternation version of the regex, thank you. – Kahsius Oct 25 '21 at 09:15

1 Answers1

0

As Wiktor Stribiżew notes in a comment, you can use ^float i.*method2.* here to match the lines (though as "function names" this might be more than you want—but at least in the git log -L output, these are just text anyway).

Ultimately, the issue here has to do with which regular expression syntax(es) Git supports.

The primary ones, generally supported, are "POSIX EREs". See What flavor of regex does git use for some additional detail. However, git grep has flags to choose different pattern types, plus grep.patternType, while -L function name arguments are passed in to parse_range_funcname in line-range.c. Annoyingly, this doesn't even use EREs, but rather BREs, due to this line:

reg_error = regcomp(&regexp, pattern, REG_NEWLINE);

This means that for -L expressions in git log, not even alternation is allowed. (git grep of course can do alternation.) This shoots down the idea suggested by The fourth bird. It might be nice if the function pattern matcher allowed EREs.

torek
  • 448,244
  • 59
  • 642
  • 775