git log -L :<funcname>:<file>中的“函数名称正则表达式”是什么?

15

我在我的文件Main/VProj/AppModel.swift中有以下的Swift函数。

    func createItemAndSegment(image:UIImage, completionHandler:(Item?, NSError?)->Void) {
        \\[...]
    }
git log -L :<funcname>:<file>的文档说明如下:

-L <start>,<end>:<file>

-L :<funcname>:<file>

跟踪“<start>,<end>”(或函数名正则表达式<funcname>)在<file>中给出的行范围的演变。

但是命令:
  • git log -L :createItemAndSegment:Main/VProj/AppModel.swift
  • git log -L :'createItemAndSegment':Main/VProj/AppModel.swift
  • git log -L :'/createItemAndSegment/':Main/VProj/AppModel.swift
都会提示错误starting at line 1: no match
当文档说:<funcname>是“函数名正则表达式”时,应该长成什么样子?
3个回答

16
funcname 应该是一个正则表达式,用于匹配函数名。没有特殊正则表达式字符的字面字符串应该是有效的正则表达式,因此您的第一个示例 git log -L :createItemAndSegment:Main/VProj/AppModel.swift 应该可以工作。
但是,为了使其工作,Git 需要能够确定哪些行是函数声明。它有一个默认的正则表达式,假定任何以字母字符、下划线或美元符号(没有前导空格)开头的行都是函数声明的开始,使用 -L :<funcname>:<file> 语法将搜索也匹配您的模式的函数声明,直到下一个函数声明或文件结束。
在某些语言中,这种启发式方法不合适。例如,如果函数或方法声明嵌套在类内部并缩进,则它将无法捕获这些声明。为此,您需要定义自定义函数头正则表达式。 .gitattributes 部分 "定义自定义块标题" 描述了如何执行此操作。首先,您需要在项目顶层创建一个类似以下内容的 .gitattributes 文件:
*.swift diff=swift

然后在您的 .git/config 或全局 ~/.gitconfig 中,您需要定义一个正则表达式来查找这些声明。我不太了解 Swift,无法确定适当的正则表达式是什么,但可能类似于以下内容(我基于 Python 的内置正则表达式 进行了构建):

[diff "swift"]
    xfuncname = ^[ \t]*((class|func)[ \t].*)$

谢谢Brian。我在想,是否更好让我使用<start>,<end>正则表达式而不是:<funcname>。我原以为后者可以避免我需要理解Swift的正则表达式,但似乎并非如此。我已经在苹果开发者论坛上发布了帖子(我的帖子正在等待审核),以防万一有人能够将Swift添加到您提到的内置git正则表达式中。 - dumbledad
我们能否将空格正则表达式直接合并到函数名正则表达式中呢?例如 '\s+func...'。我很好奇——我一直在尝试使用类似 '\s+def load' 的 Ruby 文件,但都没有成功。 - AndrewKS

0

当我尝试解释如何使用git log -L跟踪类中JS函数时,我遇到了相同的情况。最终我使用了<start><end>:<file>语法。唯一的问题是找到<end>匹配器的正确语法,以便指定精确的缩进。

这里有一个例子:

git log -L '/myFunction (params) {/','/^ }/':myClass.js

如果你在man页面中阅读官方示例,你会看到那个语法:

git log -L '/int main/',/^}/:main.c

如果你尝试将其与我的先前示例结合使用,你会得到一个错误:

$ git log -L '/myFunction (params) {/',/^  }/:myClass.js

fatal: Invalid object name '}/'.

解决方案是在<end>表达式周围使用(单)引号:/^ }/=>'/^ }/'

希望这能有所帮助。


0

funcname 应该是一个匹配函数名称的正则表达式。

确保 funcname 不是 $,否则会触发无限循环,如 "为什么在 git log -L 中使用 '$' 作为 funcname 会导致无限搜索?" 中所述。

larsks 提出了一个补丁,应该成为 Git 2.40(2023 年第一季度)的一部分。

当给定一个匹配行末空字符串的模式时,解析 "git diff"(man) 行范围的代码会陷入无限循环,这已经在 Git 2.40(2023 年第一季度)中得到了纠正。

请查看提交 4e57c88(2022年12月19日),作者为Lars Kellogg-Stedman(larsks
(由Junio C Hamano -- gitster --合并于提交 3f2e4c0,2023年1月2日)

line-range:修复使用'$'正则表达式时的无限循环错误

签名作者:Lars Kellogg-Stedman

当传递零宽度正则表达式$(例如"-L :$:line-range.c")作为 "git log"(man)-L参数时,会导致find_funcname_matching_regexp()进入无限循环。
修改find_funcname_matching_regexp以正确匹配整行而不是行尾的零宽度匹配,并更新循环条件以防止其他未发现的边角情况导致无限循环。
主要更改是在将开始行标记'bol'与'\n'进行比较之前,我们对其进行了预减量。
在'$'的情况下,我们匹配行末的'\n'并以bol == eol开始循环,这确保bol将找到发生匹配的行的开头。

现在您将获得:

$ git log -L :$:main.go
fatal: -L parameter '$' starting at line 1: no match

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接