【问题标题】:list changed function names or signatures with git diff (c++)使用 git diff (c++) 列出更改的函数名称或签名
【发布时间】:2022-02-14 11:16:16
【问题描述】:

我正在开发一个 git diff 解析器。主要任务是查找所有更改的函数签名。有时在带有@@@ ...的块行中。@@@ 包含这些信息,但有时不包含。 上次我在 greet() cout 消息中进行了更改,它在第一张图像上显示为更改的行并且它是正确的,但在 @@@... 行上方出现“void functOne() {”并且没有更改。 第二张图是关于测试 git diff 的虚拟 cpp 源代码。

主要问题是
如何列出所有更改的函数签名?
为什么有时会出现函数名不变?
为什么有时没有出现与@@@....一致的任何函数名称/签名?

【问题讨论】:

  • 您确实注意到,如果不解析整个文件,您就无法确定没有 100% 的确定性? “函数”可能只是在多行注释或跨越多行的字符串文字中注释掉的东西......更不用说预处理器宏产生函数签名的可能性(甚至可能没有定义在您正在分析的文件中)...
  • 另请注意,显示的代码似乎缺少分号。如果要解析的代码在语法上无效,那么解析过程肯定不会变得更容易。要正确执行此操作,您可能需要一个基于诸如 clang 的 libTooling 之类的工具,该工具可以解析正在比较的文件的版本并以合适的格式生成输出。
  • 不要发布文字图片,尤其是代码!将文本作为文本复制粘贴到您的问题中。
  • 我想到了一些关于解析的场景,但主要问题是那棵树以及关于 git diff 的所有内容,而不是关于解析。

标签: c++ git parsing diff signature


【解决方案1】:

有时在块行中带有@@@ ....@@@

Git 将其称为 hunk header(在其他 diff 软件也如此称呼它之后)。

...包含[函数名]但有时不包含。

Git 放入 diff hunk 标头的函数部分的内容是通过将前面的行与特定的正则表达式匹配生成的,例如 xfuncname 下的 described in the gitattributes documentation(搜索该字符串)。但请注意,这是一个正则表达式,而正则表达式天生就没有解析器的能力;总会存在可以解析的有效 C++ 构造,但不能被您可以编写的某些正则表达式识别。

如果 Git 内置的 C++ xfuncname 模式不适合您使用,您可以编写自己的模式。但它总是会受到限制因为正则表达式只能识别正则语言(这些是 CS 理论或信息学术语,不能解释为普通英语;有关更多信息,请参阅 @987654322 @)。

【讨论】:

    【解决方案2】:

    git diff 命令不关心任何功能。 git 存储库可以包含任何类型的文本文件(二进制文件也是如此,但这在这里无关紧要),而不仅仅是 C++ 源代码。

    diff 命令不会尝试以任何方式解释文件。只有 C++ 编译器才能完全理解 C++ 文件并处理所有函数声明。

    diff 命令仅查找已更改的离散的文本行,并将它们与前后几行未更改的行一起显示。

    如果更改的行恰好位于函数声明的开头,那么这将包括函数声明。如果它们在一个长函数的中间,你只会看到前面几行,就是这样。

    有 git diff 选项可以控制显示多少未更改的行(查看 git 的文档)。例如,指定一百万行会导致显示整个文件,并标记所有更改的行。

    如果您愿意,您可以这样做,然后尝试自己找出所有更改的函数的名称,但是在您自己编写一个完整的 C++ 编译器之前,您的启发式解析尝试不会 100% 正确。您可能已经注意到,隐藏在 git diff 输出中的指示表明 git 猜测更改的函数 可能 是什么。但是,由于 git 也不是 C++ 编译器,所以偶尔也会出错。

    【讨论】:

    • 感谢您的回答,但您错了,因为当我删除中间较长(60 行)函数的行时,@@@... 的行包含签名。如果我正确默认, git diff 结果中的上下文 a 是 +-3 行。在原始发布的代码中是耻辱,因为“void functionOne() {”行与更改后的代码相差三行。如果我使用 -U0 切换上下文行 +- 为 0,但在带有 @@@.... 的行中仍然包含签名。
    • 我到底在哪里声称 git 总是出错?您的观察中哪一部分与“这也是错误的,偶尔”的说法相矛盾?
    • 抱歉,我不完全理解您最后的评论。
    • 我的回答只说了一件事:git不是C++编译器,只有C++编译器才能完全理解一个c++程序,而git只比较单独的文本行,它只做一个最好猜测更改后的函数名称,这有时会出错。这几乎是我的回答所说的唯一内容。因此,“你错了”可能只是因为在调整了一些东西之后 git 显示了正确的函数名称,当我写“也错了,偶尔”时,我一定是错了。当然,这不是真的。一个不排除另一个。
    猜你喜欢
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-09
    • 2020-05-05
    相关资源
    最近更新 更多