'Git Diff at method level
I am looking at getting information on all the methods/function Added , Deleted and Modified between any two commits
Notes -
Code Base is in Java and on Github
Utlimate Goal - I must be able to get all the Deleted, Modified(Both source code modification and renaming of methods) and Newly added Methods between any two commits spanning across sub-packages and classes
More pleased if full method signature is returned along with fully qualified method name
Things I Tried
git Diff
- Link - but the Diff history is huge and I'm really only interested in the changes of methods added, deleted or modified (ie in Java lists the class but not the function)git log -L :function:path/to/file
- prints the change history of that function, doesn't do what I intend to do and watchers are on a specific function but not on whole git repo. Another limitation is of getting diff between two commits.
Desired Results
Diff between any two commits should return
Methods Added ->
myMethod12 - path/to/class
myMethod34 - path/to/class
Methods Deleted ->
myMethod3 - path/to/class
myMethod11 - path/to/class
Methods Renamed ->
(Previous Name) (Revised Name) (Path)
myMethod6 yourMethod32 path/to/class
Methods Modified (source code modifs) ->
myMethod44 - path/to/class
or ideally the fully qualified method name
ie
Methods Added ->
com.example.subp.subp2.nestedpack.addMessages(Message[] msgs)
...
Solution 1:[1]
Git is a general tool. It does not understand your source language (in this case Java, but what if your source language were instead Swift or Python or C++ or TypeScript or, well, whatever else you can think of?). It just understands "lines of text" and has simple (or sometimes, not-very-simple) regular expressions to recognize function / method / class / other such definitions, to annotate diffs.1
To get the kind of output you want, you need a tool that does understand the language in question.
Given such a tool, you will give it:
- an older version (a commit or a file from that commit), and
- a newer version (another commit, or "the same" file from that commit).
It should then read those two commits' files, figure out what methods you have, and produce whatever analysis you like.
What this tool needs from Git is two versions. When and whether it can handle just getting two files, or needs two entire snapshots, depends on that tool.
The git difftool
command may, or may not, be helpful for invoking this other tool. What git difftool
does is compare two entire commits, then, for each differing file, feed the old and new versions of those files to another tool. You choose that second tool, from any tool you have on your computer, anywhere. Git merely invokes that tool, on the pair of files extracted from the pair of commits. If this does what you need, you're now done. If not, you may need some more steps: for instance, you might want to run git diff --raw <commit1> <commit2>
and parse its output, or just git checkout
each of the two commits into some temporary locations (using a temporary index for each) and work from there.
1Note that regular expressions are not capable of proper parsing; most real languages require a grammar. See, e.g., Regular Expression Vs. String Parsing. A proper CS-theoretic discussion will get into Finite State Automata but is generally off topic on StackOverflow.
Solution 2:[2]
First of all, git works with text and isn't responsible for indexing your sources, searching for methods definitions, etc.
So, probably, the best solution is diff. Here is described how to use diff between specific commits.
From myself I would like to encourage you for using diff for specific file: git diff specific-file
and using grep
if diff is huge:
git diff | grep -e method-name -e public -e private -e void -e etc
I hope you will invent more suitable command for your goals. Good luck!
Solution 3:[3]
I don’t know of a tool that does exactly that.
In order to do something like that you need a Java-aware diff tool. difftastic supports Java. You get output like this (diff on some random BSD-3 licensed code):
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Oleh Samoilenko |
Solution 3 | Guildenstern |