如何使用Git在代码库的不同版本之间识别函数更改?

3
我有一个包含许多C文件的存储库。给定两个提交的SHA哈希值,<commit-sha-1><commit-sha-2>,我想编写一个脚本(可能是bash/ruby/python),以检测这两个提交之间在存储库中的C文件中已更改的函数。
我目前正在查看git loggit commitgit diff文档。如果有人之前做过类似的事情,可以给我一些指针,告诉我从哪里开始或如何继续。

1
也许值得检查一下您所做更改的输出结果,但是使用 gif diff-W/--function-context 标志可能是一个不错的起点。 - Chris
2个回答

2

看起来不太好,但你可以将git和你最喜欢的标记系统(如GNU global)结合起来实现这一点。例如:

#!/usr/bin/env sh

global -f main.c | awk '{print $NF}'  | cut -d '(' -f1 | while read i
do
    if [ $(git log -L:"$i":main.c HEAD^..HEAD | wc -l) -gt 0 ]
    then
        printf "%s() changed\n" "$i"
    else
        printf "%s() did not change\n" "$i"
    fi
done

首先,您需要在项目中创建一个函数数据库:

$ gtags .

运行上述脚本,查找自上次提交以来在main.c中被修改的函数。当然,该脚本可以更加灵活,例如它可以处理所有*.c文件,这些文件是由git diff --stats报告的两个提交之间的更改。

在脚本内部,我们使用git log-L选项:

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

       Trace the evolution of the line range given by
       "<start>,<end>" (or the function name regex <funcname>)
       within the <file>. You may not give any pathspec
       limiters. This is currently limited to a walk starting from
       a single revision, i.e., you may only give zero or one
       positive revision arguments. You can specify this option
       more than once.

1

请参见this question">此问题。

Bash脚本:

#!/usr/bin/env bash

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

解释:

1: 获取差异

2: 获取仅带有块标题的行;如果一个块标题的“可选部分标题”存在,则它将是修改后函数的函数定义

3: 选择只包含开括号的块标题,因为它们将包含函数定义

4: 在行中去掉“@@ [旧文件范围] [新文件范围] @@”部分

5: 在开括号之后去掉所有内容

6: 从指针中去掉“*”

7: [参见'awk']:打印记录(即行)的最后一个字段(即列)。

8: 去掉重复的名称。


你可以标记自己的答案,这样会使其他有类似问题的人受益。 - Marina Liu

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