/** * Copyright 2015 GitFx * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package io.github.gitfx.data; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.diff.DiffEntry; import org.eclipse.jgit.diff.DiffFormatter; import org.eclipse.jgit.diff.RawTextComparator; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.AbstractTreeIterator; import org.eclipse.jgit.treewalk.CanonicalTreeParser; import org.eclipse.jgit.util.io.DisabledOutputStream; // import org.slf4j.Logger; // import org.slf4j.LoggerFactory; import com.jcabi.aspects.Loggable; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * * @author rvvaidya */ @Loggable public class GitRepoMetaData { //[LOG] Logger logger = LoggerFactory.getLogger(GitRepoMetaData.class.getName()); Repository repository; RevCommit commit; RevWalk walk; ArrayList<String> shortMessage; ArrayList<ArrayList<String>> commitHistory; ArrayList<String> tempCommitHistory; ArrayList<String> commitSHA; final String ADD = "ADD"; final String MODIFY= "MODIFY"; final String DEL ="DEL"; String diff = null; //There should be a better way to get this count int commitCount = 0; public GitRepoMetaData() { shortMessage = new ArrayList<>(); commitHistory = new ArrayList<ArrayList<String>>(); tempCommitHistory = new ArrayList<>(); commitSHA = new ArrayList<>(); } public void setRevWalk(RevWalk walk) { this.walk = walk; } public void setRepository(Repository repository) { this.repository = repository; } public void setRevCommit(RevCommit commit) { this.commit = commit; } //Gets the short messages to be printed on Titled Pane //Also populates the commitHistory container to show history in the accordion public ArrayList<String> getShortMessage() { for (RevCommit revision : walk) { shortMessage.add(revision.getShortMessage()); //[LOG] logger.debug(revision.getShortMessage()); DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE); df.setRepository(repository); df.setDiffComparator(RawTextComparator.DEFAULT); df.setDetectRenames(true); RevCommit parent = null; if(revision.getParentCount()!=0) { try { parent = walk.parseCommit(revision.getParent(0).getId()); RevTree tree = revision.getTree(); List<DiffEntry> diffs = df.scan(parent.getTree(), revision.getTree()); for (DiffEntry diff : diffs) { String changeType = diff.getChangeType().name(); if(changeType.equals(ADD)|| changeType.equals(MODIFY)) { //[LOG] logger.debug(diff.getChangeType().name()); //[LOG] logger.debug(diff.getNewPath()); tempCommitHistory.add(diff.getNewPath()); } } }catch (IOException ex) { //[LOG] logger.debug("IOException", ex); } } commitSHA.add(commitCount,revision.name()); commitHistory.add(commitCount++,new ArrayList<String>(tempCommitHistory)); tempCommitHistory.clear(); } walk.reset(); return shortMessage; } private static AbstractTreeIterator prepareTreeParser(Repository repository, String objectId) throws IOException, MissingObjectException, IncorrectObjectTypeException { RevWalk walk = new RevWalk(repository) ; RevCommit commit = walk.parseCommit(ObjectId.fromString(objectId)); RevTree tree = walk.parseTree(commit.getTree().getId()); CanonicalTreeParser oldTreeParser = new CanonicalTreeParser(); ObjectReader oldReader = repository.newObjectReader(); oldTreeParser.reset(oldReader, tree.getId()); walk.dispose(); return oldTreeParser; } //Given a commit index this API returns the diff between a commit and its parent. //Assuming only 1 parent. public String getDiffBetweenCommits(int commitIndex) throws IOException,GitAPIException{ if(commitIndex+1==commitCount) return "Nothing to Diff. This is first commit"; AbstractTreeIterator current = prepareTreeParser(repository,commitSHA.get(commitIndex)); AbstractTreeIterator parent = prepareTreeParser(repository,commitSHA.get(++commitIndex)); ObjectReader reader = repository.newObjectReader(); ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); // finally get the list of changed files Git git = new Git(repository) ; List<DiffEntry> diff = git.diff(). setOldTree(parent). setNewTree(current). //TODO Set the path filter to filter out the selected file //setPathFilter(PathFilter.create("README.md")). call(); for (DiffEntry entry : diff) { System.out.println("Entry: " + entry + ", from: " + entry.getOldId() + ", to: " + entry.getNewId()); DiffFormatter formatter = new DiffFormatter(byteStream) ; formatter.setRepository(repository); formatter.format(entry); } return byteStream.toString(); } public ArrayList<ArrayList<String>> getCommitFiles() { return commitHistory; } public ArrayList<String> getCommitRef(){ return commitSHA; } public String getRepoName() { String repoPath = repository.getDirectory().getParent(); int index = repoPath.lastIndexOf("/"); return repoPath.substring(index + 1); } //Gets commit count for this repository public int getCommitCount() { return commitCount; } }