Using git to identify all modified functions in a revision

可紊 提交于 2019-12-17 09:55:51

问题


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...

  1. Picks the current diff,
  2. next picks only lines with "hunk-headers" ,
  3. next picks only lines with opening parenthesis (as potentially containing function names),
  4. next ignores the hunk headers,
  5. next ignores the text after the opening parenthesis,
  6. next picks only the word immediately before the opening parenthesis,
  7. 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?

  1. Create the filter: java-ls-methods.groovy is an implementation of such a filter using Groovy and Spoon
  2. Register this filter in git: git config diff.java-ls-methods.textconv /home/path/to/java-ls-methods.groovy
  3. Associate this filter with Java files: echo "*.java diff=java-ls-methods" >> .gitattributes
  4. Make the diff: git diff (diff against last commit) or git diff master (diff against another branch)
  5. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!