使用 git diff (c++) 列出更改的函数名称或签名

list changed function names or signatures with git diff (c++)

我正在研究 git 差异解析器。主要任务是找到所有改变的函数签名。有时在块行中带有@@@ .... @@@ 包含这些信息但有时不包含。 上次我更改了 greet() cout 消息,它在第一张图像上显示为更改的行,它是正确的,但在 @@@... 行上方出现“void functOne() {”并且没有更改。 第二张图片是关于用于测试 git diff.

的虚拟 cpp 源代码

主要问题是
如何列出所有已更改函数的签名?
为什么有时会出现未更改的函数名称?
为什么有时候不出现符合@@@....的函数name/signature?

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

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

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

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

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

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

Sometimes in the chunk line with @@@ .... @@@

Git 称其为 hunk header(在其他 diff 软件也这么称呼它之后)。

... contains [the function name] but sometimes not.

Git 将 放入 差异块 header 的函数部分是通过将较早的行与特定的正则表达式进行匹配而产生的,因为 described in the gitattributes documentationxfuncname 下(搜索该字符串)。但请注意,这是一个正则表达式,而正则表达式本质上不如解析器强大;总会存在可以解析的有效 C++ 构造,但无法被您编写的某些正则表达式识别。

如果 Git 的内置 C++ xfuncname 模式不适合您的使用,您可以编写自己的模式。但它总是会受到限制因为正则表达式只能识别正则语言(这些是CS-theoretical或信息学术语,不能解释为普通英语;更多信息,请参见, 例如 Regular vs Context Free Grammars).