问题
Is there a good way to use git to identify all the modified functions in each revision in the history? I've tried using the -p switch, but it doesn't seem to work in the same way that svn's show-c-function parameter works.
My assumption is that I'll want to use "git diff HEAD~i HEAD~i-1 -p" for increasing values of i. Am I missing some parameters that will help identify diff's best guess on the functions that were modified?
回答1:
Here's a quick and dirty attempt at what I think you're going for. It does a git log
to show all revisions, -p
to include the diff in the log, a grep
to only include the lines containing the commit ID and the hunk headers, and uses sed
to filter out the line numbers, leaving only the guess at the function name that Git writes after the hunk header.
git log -p | grep -E '^(commit|@@)' | sed 's/@@.*@@//'
回答2:
Here is a magic chant to list functions within a git diff
*
git diff | \
grep -E '^(@@)' | \
grep "(" | \
sed 's/@@.*@@//' | \
sed 's/(.*//' | \
awk -F " " '{print $NF}' | \
uniq
...and what it does is...
- Picks the current diff,
- next picks only lines with "hunk-headers" ,
- next picks only lines with opening parenthesis (as potentially containing function names),
- next ignores the hunk headers,
- next ignores the text after the opening parenthesis,
- next picks only the word immediately before the opening parenthesis,
- and lastly ignores multiple occurrences of the same word in the list.
Voila! you have a list of functions being modified by the current git diff
.
* Verified using git version 2.7.4
on Ubuntu 16.04 running bash.
回答3:
You can list all modified functions in a revision by using git textconv filters. The idea is to create a specific filter that lists all functions/methods, and for all functions, a checksum of the body. This gives this kind of filtered textconv view:
m() 12
bar() 42
(here m()
is a function signature, 12
is a checksum of its body))
When git diff
uses this filter on the two versions before and after the revision:
- if a function is added, a line is added in the diff
Example: foo is added
m() 12
+ foo() 24
bar() 42
- if a function is modified, the checksum changes, and a line is updated in the diff
Example: the body of foo is modified
m() 12
- foo() 23
+ foo() 24
bar() 42
How to do that?
- Create the filter: java-ls-methods.groovy is an implementation of such a filter using Groovy and Spoon
- Register this filter in git:
git config diff.java-ls-methods.textconv /home/path/to/java-ls-methods.groovy
- Associate this filter with Java files:
echo "*.java diff=java-ls-methods" >> .gitattributes
- Make the diff:
git diff
(diff against last commit) orgit diff master
(diff against another branch) - Once your diff is done, comment the line in
.gitattributes
to go back to a normal diff
Credits: solution inspired from https://stackoverflow.com/a/16929266
来源:https://stackoverflow.com/questions/5721447/using-git-to-identify-all-modified-functions-in-a-revision