6

When we do git log --shortstat we get the number of lines inserted, deleted, and changed. Something like:

1 file changed, 9 insertions(+), 3 deletions(-)

Please help me with getting the number of lines inserted, deleted, and changed.

  1. I am doing a repository clone to get git project on local machine. Here is the same code:

     RepoClone repoClone = new RepoClone();
     repoClone.repoCloner();
     repository = builder.setGitDir(repoClone.repoDir).setMustExist(true).build();
    
  2. I am even able to get a TreeWalk:

     TreeWalk treeWalk = getCommitsTreeWalk();
    
  3. I am able to retrieve file name, count of number of commits per file, LOC, and the number of developers who worked on each xml/ java file.

     while (treeWalk.next()) {
       if (treeWalk.getPathString().endsWith(".xml") || treeWalk.getPathString().endsWith(".java")) {
         jsonDataset = new JSONObject();
         countDevelopers = new HashSet<String>();
         count = 0;
         logs = new Git(repository).log().addPath(treeWalk.getPathString()).call();
         for (RevCommit rev: logs) {
           countDevelopers.add(rev.getAuthorIdent().getEmailAddress());
           count++;
         }
         jsonDataset.put("FileName", treeWalk.getPathString());
         jsonDataset.put("CountDevelopers", countDevelopers.size());
         jsonDataset.put("CountCommits", count);
         jsonDataset.put("LOC", countLines(treeWalk.getPathString()));
         commitDetails.put(jsonDataset);
       }
     }
    
  4. Now, I want to retrieve the number of lines inserted and deleted for each file.

Ragunath Jawahar
  • 19,513
  • 22
  • 110
  • 155
SJ03
  • 61
  • 4

1 Answers1

9

The following code snippet compares two commits and prints the changes. diffFormatter.scan() returns a list of DiffEntrys which each describes an added, deleted or modified file. Each of the diff entries in turn has a list of HunkHeaders which desribe the changes within that file.

// Create two commits to be compared
File file = new File( git.getRepository().getWorkTree(), "file.txt" );
writeFile( file, "line1\n" );
RevCommit oldCommit = commitChanges();
writeFile( file, "line1\nline2\n" );
RevCommit newCommit = commitChanges();

// Obtain tree iterators to traverse the tree of the old/new commit
ObjectReader reader = git.getRepository().newObjectReader();
CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
oldTreeIter.reset( reader, oldCommit.getTree() );
CanonicalTreeParser newTreeIter = new CanonicalTreeParser();
newTreeIter.reset( reader, newCommit.getTree() );

// Use a DiffFormatter to compare new and old tree and return a list of changes
DiffFormatter diffFormatter = new DiffFormatter( DisabledOutputStream.INSTANCE );
diffFormatter.setRepository( git.getRepository() );
diffFormatter.setContext( 0 );
List<DiffEntry> entries = diffFormatter.scan( newTreeIter, oldTreeIter );

// Print the contents of the DiffEntries
for( DiffEntry entry : entries ) {
  System.out.println( entry );
  FileHeader fileHeader = diffFormatter.toFileHeader( entry );
  List<? extends HunkHeader> hunks = fileHeader.getHunks();
  for( HunkHeader hunk : hunks ) {
    System.out.println( hunk );
  }
}

I think with the information provided by DiffEntry and HunkHeader you should be able to get the desired --shortstat.

Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79
  • Thanks a lot! i will try this code to get --shortstat kind of results .For this kind of comparison, is it possible to get previous commits from a repository for a file and compare? i want to compare commits "in a month" and produce number of lines inserted and deleted. – SJ03 Feb 25 '15 at 20:31
  • 1
    The difficult part here is probably to find the first and last commit in a given month. If you start with the last commit in a month, you can traverse its parents to the first one. But if a merge commit (a commit with two parents) is in between, you need a policy which _path_ to follow. – Rüdiger Herrmann Feb 26 '15 at 19:54
  • Ohk. In my case, I have only single branch, that is, the "master" branch. If i want to compare commits in a single branch, would it be possible. Thanks! – SJ03 Feb 26 '15 at 21:35