From my understanding you would simply need to combine the diffs of the parents of the merge commit with their respective parents.
The snippet below creates two commits with each one file added (main.txt
and side.txt
), the merge commit is then diffed as described above
public void diffMerge() throws Exception {
RevCommit baseCommit = commitChanges();
Ref sideBranch = git.branchCreate().setName( "side" ).call();
File mainFile = new File( git.getRepository().getWorkTree(), "main.txt" );
mainFile.createNewFile();
RevCommit mainCommit = commitChanges();
git.checkout().setName( sideBranch.getName() ).call();
File sideFile = new File( git.getRepository().getWorkTree(), "side.txt" );
sideFile.createNewFile();
RevCommit sideCommit = commitChanges();
git.checkout().setName( "refs/heads/master" ).call();
ObjectId mergeCommitId = git.merge().include( sideCommit ).call().getNewHead();
DiffFormatter diffFormatter = new DiffFormatter( NullOutputStream.INSTANCE );
diffFormatter.setRepository( git.getRepository() );
RevCommit mergeCommit = parseCommit( mergeCommitId );
List<DiffEntry> mainEntries = diffFormatter.scan( parseCommit( mergeCommit.getParent( 0 ) ).getParent( 0 ), mergeCommit.getParent( 0 ) );
List<DiffEntry> sideEntries = diffFormatter.scan( parseCommit( mergeCommit.getParent( 1 ) ).getParent( 0 ), mergeCommit.getParent( 1 ) );
diffFormatter.close();
mainEntries.forEach( entry -> System.out.println( entry.getNewPath() ) );
sideEntries.forEach( entry -> System.out.println( entry.getNewPath() ) );
}
private RevCommit parseCommit( ObjectId commitId ) throws IOException {
try( RevWalk revWalk = new RevWalk( git.getRepository() ) ) {
return revWalk.parseCommit( commitId );
}
}
private RevCommit commitChanges() throws GitAPIException {
git.add().addFilepattern( "." ).call();
return git.commit().setMessage( "commit message" ).call();
}
Note that the code blindly assumes the the parents of the merge commits aren't merges themselves.