Originally Posted By: Roger
Originally Posted By: peter
a regex can't count the brace pairs


Absolutely true, but if git's using PCRE, those aren't regexes in the technical sense, and here's some Perl that uses a "regex" to match the brace pairs: http://stackoverflow.com/a/133771/8446

Git's use of PCRE is spotty. git-grep uses it (with the -P switch), but git-blame has no equivalent, and does not use PCRE. The simple test is to use an embedded modifier:
Code:
$ git grep '(?i)pauseexec' ../../omanalyze.cpp
$ git grep -P '(?i)pauseexec' ../../omanalyze.cpp
../../omanalyze.cpp:int pauseExec(int value)
../../omanalyze.cpp:    exit(pauseExec(1));
../../omanalyze.cpp:    exit(pauseExec(1));
../../omanalyze.cpp:            return pauseExec(0);
../../omanalyze.cpp:    return pauseExec ( 0 );
$ git blame -L '/pauseExec/,/}/' ../../omanalyze.cpp
8a714b87 (canuck 2015-05-15 16:10:54 +0000 37) int pauseExec(int value)
8a714b87 (canuck 2015-05-15 16:10:54 +0000 38) {
8a714b87 (canuck 2015-05-15 16:10:54 +0000 39)     if (pauseAtExit) {
8a714b87 (canuck 2015-05-15 16:10:54 +0000 40)         printf("hit return to exit...");
8a714b87 (canuck 2015-05-15 16:10:54 +0000 41)         char buf[ 128 ];
8a714b87 (canuck 2015-05-15 16:10:54 +0000 42)         if (fgets(buf, sizeof(buf) - 1, stdin));
8a714b87 (canuck 2015-05-15 16:10:54 +0000 43)     }
$ git blame -L '/(?i)pauseexec/,/}/' ../../omanalyze.cpp
fatal: -L parameter '(?i)pauseexec' starting at line 1: No match


Part of the problem that Tony's facing is that -L takes 2 parameters -- the start of the range, and the end of the range. Those are independent regex, so he can't use back references to match indent (/^(\s*)funcName/,/^\1}/ won't work), nor would any fancy PCRE, even if it were available.

On first look, the -L :<funcname> option seems like it's the answer:
Code:
$ git blame -L :'pauseExec' ../../omanalyze.cpp
8a714b87 (canuck 2015-05-15 16:10:54 +0000 37) int pauseExec(int value)
8a714b87 (canuck 2015-05-15 16:10:54 +0000 38) {
8a714b87 (canuck 2015-05-15 16:10:54 +0000 39)     if (pauseAtExit) {
8a714b87 (canuck 2015-05-15 16:10:54 +0000 40)         printf("hit return to exit...");
8a714b87 (canuck 2015-05-15 16:10:54 +0000 41)         char buf[ 128 ];
8a714b87 (canuck 2015-05-15 16:10:54 +0000 42)         if (fgets(buf, sizeof(buf) - 1, stdin));
8a714b87 (canuck 2015-05-15 16:10:54 +0000 43)     }
[...]
8a714b87 (canuck 2015-05-15 16:10:54 +0000 46) }
8a714b87 (canuck 2015-05-15 16:10:54 +0000 47) 


However, -L :<funcname> doesn't understand indented definitions. For example, suppose the following code:
Code:
class fooImpl
{
    [...]

    static bool limitMemoryFootprint()
    {
        switch(m_platform) {
        // [...]
        }
    }

    [...]
}


Then looking for the limitMemoryFootprint() method fails:
Code:
$ git blame -L :'limitMemoryFootprint' test.cc
fatal: -L parameter 'limitMemoryFootprint' starting at line 1: no match


Remove the indentation, and it works just fine.

I'd say that Tony's best bet is to figure out the start and end line numbers of the function outside of git, and use those rather than regex parameters to the -L option (caution: line-noise ahead):
Code:
$ perl -ne'if(/pauseExec/){$a=$.;tr/{/{/||next}if($a){$b+=tr/{//;$b-=tr/}//;$b||exit print "$a,$.\n"}' ../../omanalyze.cpp 
37,46
$ git blame -L 37,46 ../../omanalyze.cpp
8a714b87 (canuck 2015-05-15 16:10:54 +0000 37) int pauseExec(int value)
8a714b87 (canuck 2015-05-15 16:10:54 +0000 38) {
8a714b87 (canuck 2015-05-15 16:10:54 +0000 39)     if (pauseAtExit) {
[...]
8a714b87 (canuck 2015-05-15 16:10:54 +0000 46) }