使用git来识别修订版中所有修改过的函数

4
有没有一种好的方法使用git来识别历史中每个版本中所有修改过的函数?我尝试使用-p开关,但它似乎不能像svn的show-c-function参数那样工作。
我的假设是,我将想要使用“git diff HEAD~i HEAD~i-1 -p”来增加i的值。我是否错过了一些参数,可以帮助确定diff对哪些函数进行了修改的最佳猜测?

你能否更清楚地解释一下你想要的是什么?你想要复制Subversion中的show-c-function行为吗?你希望它如何识别已更改的函数?你希望输出看起来像什么? - Brian Campbell
对于每个版本,如果一个 .c 文件受到影响并且某个函数发生了变化,我想要相应的函数定义。例如,如果 int foo() 的主体被更改,我希望以类似 svn show-c-function 的方式看到 "int foo()"。 - swrittenb
我想知道是否有专门为JavaScript构建的东西。那将是很棒的。 - sktguha
对于Java,请参见 https://github.com/monperrus/git-api-diff 的原型。 - Martin Monperrus
3个回答

9

这是一个神奇的咒语,用于列出在 git diff * 中的函数。

git diff |                  \
grep -E '^(@@)' |           \
grep "(" |                  \
sed 's/@@.*@@//' |          \
sed 's/(.*//' |             \
awk -F " " '{print $NF}' |  \
uniq

...它所做的是...

  1. 选择当前的差异(diff),
  2. 接下来只选择带有"hunk-headers"的行,
  3. 接下来只选择包含函数名可能性的开括号中的行,
  4. 接下来忽略hunk headers,
  5. 接下来忽略开括号后的文本,
  6. 接下来只选择开括号前面的单词,
  7. 最后在列表中忽略相同单词的多次出现。

Voila! 现在你有了一个被当前git diff修改的函数列表。


* 在运行bash的Ubuntu 16.04上使用git version 2.7.4进行验证。


此外,如果函数定义被打印在差异中,则无法正常工作,因为它不会被打印为标题。从标题中提取效果很好。 - Loren
1
为了使其正常工作,您必须拥有一个.gitattributes文件,指定每个文件的语言,以便diff找到正确的头文件。创建该文件的说明:https://dev59.com/G2s05IYBdhLWcg3wQvyq#7347993 - Loren
对于C/C++,还可以通过去除前导*来改进。 - zr.

4

这是我尝试翻译的内容,它会执行git log来显示所有版本,-p用于在日志中包含差异,使用grep仅包括包含提交ID和块标题的行,并使用sed过滤掉行号,只留下Git在块标题后写的函数名称猜测。

git log -p | grep -E '^(commit|@@)' | sed 's/@@.*@@//'

这个解决方案已经过时,不适用于 git 版本 >= 2.7.4。能否请您更新一下呢?谢谢。 - UnchartedWaters

0

您可以使用git文本转换过滤器列出修订版本中所有修改的函数。其思想是创建一个特定的过滤器,列出所有函数/方法,并为所有函数计算主体的校验和。这将提供这种类型的过滤器文本转换视图:

m() 12
bar() 42

(这里m()是函数签名,12是其主体的校验和)

git diff在修订前后的两个版本上使用此过滤器时:

  • 如果添加了一个函数,则差异中会添加一行

例如:添加了foo

m() 12
+ foo() 24 
bar() 42
  • 如果修改了一个函数,校验和会改变,并且差异中的一行将被更新

例如:修改了foo的主体

m() 12
- foo() 23 
+ foo() 24 
bar() 42

如何做到这一点?

  1. 创建过滤器:java-ls-methods.groovy 是使用 Groovy 实现此类过滤器的示例,Spoon
  2. 在 git 中注册此过滤器:git config diff.java-ls-methods.textconv /home/path/to/java-ls-methods.groovy
  3. 将此过滤器与 Java 文件关联:echo "*.java diff=java-ls-methods" >> .gitattributes
  4. 进行差异比较:git diff(与上次提交进行比较)或 git diff master(与另一个分支进行比较)
  5. 完成差异比较后,在 .gitattributes 中注释该行以返回正常差异

致谢:解决方案灵感来自 https://dev59.com/YG445IYBdhLWcg3wmLdd#16929266


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