【问题标题】:Using git to identify all modified functions in a revision使用 git 识别修订中的所有修改函数
【发布时间】:2011-08-08 22:49:48
【问题描述】:

有没有什么好办法可以用git来识别历史中每个修订版中所有修改过的函数?我尝试过使用 -p 开关,但它的工作方式似乎与 svn 的 show-c-function 参数的工作方式不同。

我的假设是我想使用“git diff HEAD~i HEAD~i-1 -p”来增加 i 的值。我是否遗漏了一些有助于识别 diff 对已修改函数的最佳猜测的参数?

【问题讨论】:

  • 你能更清楚地解释一下你在找什么吗?您试图复制的 Subversion 的 show-c-function 行为是什么?您希望它如何识别更改的功能?您希望输出是什么样的?
  • 对于每个版本,如果 .c 文件受到影响并且函数内部发生了一些变化,我希望有相应的函数定义。例如,如果 int foo() 的主体发生了变化,我希望以类似于 svn 的 show-c-function 的方式看到“int foo()”。
  • 我想知道是否有专门为 javascript 构建的东西。那太好了
  • 对于Java,请参阅github.com/monperrus/git-api-diff的原型

标签: git function diff history revision


【解决方案1】:

这是我认为你想要的快速而肮脏的尝试。它使用git log 显示所有修订,-p 将差异包含在日志中,grep 仅包含包含提交 ID 和块头的行,并使用 sed 过滤掉该行数字,只留下对 Git 在大块头之后写的函数名称的猜测。

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

【讨论】:

  • 此解决方案已过时,不适用于 git 版本 >= 2.7.4。你能不能更新一下。谢谢。
【解决方案2】:

这是一个魔法颂歌,用于列出git diff *

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

...而它的作用是...

  1. 选择当前差异,
  2. next 只选择带有“hunk-headers”的行,
  3. next 只选择带左括号的行(因为可能包含函数名称),
  4. 下一步忽略大块头,
  5. next 忽略左括号后的文本,
  6. next 只选择左括号之前的单词,
  7. 最后忽略列表中多次出现的相同单词。

瞧!你有一个被当前git diff修改的函数列表。


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

【讨论】:

  • 此外,如果函数定义打印在 diff 中,则它不起作用,因为它不会作为标题打印。从标题中提取效果很好。
  • 为此,您需要有一个 .gitattributes 文件指定每个文件的语言,以便 diff 找到正确的标题。创建说明:stackoverflow.com/a/7347993/3854385
  • 对于 C/C++ 也可以通过去除前导 * & 来改进
【解决方案3】:

您可以使用 git textconv 过滤器列出修订中的所有修改函数。这个想法是创建一个特定的过滤器,列出所有函数/方法,并为所有函数创建一个主体的校验和。这给出了这种过滤后的 textconv 视图:

m() 12
bar() 42

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

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

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

示例:添加了 foo

m() 12
+ foo() 24 
bar() 42
  • 如果修改了函数,校验和会改变,diff 中的一行会更新

示例: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://stackoverflow.com/a/16929266

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    • 2014-06-19
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多