package bluej.groupwork.git;

import bluej.Config;
import bluej.utility.Debug;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.lib.BranchTrackingStatus;
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.revwalk.filter.RevFilter;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import threadchecker.OnThread;
import threadchecker.Tag;


| Class containing static methods for manipulating/navigating Git tree. | | @author heday | public class GitUtilities {
| Given a objectID, returns the RevTree it belongs to. | | @param repo the repository | @param objID the objectId | @return the tree if found. | @throws IncorrectObjectTypeException | @throws IOException | public static RevTree getTree(Repository repo, ObjectId objID) throws IncorrectObjectTypeException, IOException { RevTree tree; try (RevWalk walk = new RevWalk(repo)) { RevCommit commit = walk.parseCommit(objID); tree = walk.parseTree(commit.getTree().getId()); } return tree; }
| Get the diffs between two revisions. | | @param repo reference to the repository | @param revId the commit (branch, etc) to diff to | @param forkPoint the commit to diff from | public static List getDiffs(Git repo, String revId, RevCommit forkPoint) { if (forkPoint == null) { return Collections.emptyList(); } List<DiffEntry> diffs = new ArrayList<>(); try { ObjectId master = repo.getRepository().resolve(revId); RevTree masterTree = getTree(repo.getRepository(), master); ObjectId branchBId = repo.getRepository().resolve(forkPoint.getName()); RevTree ForkTree = getTree(repo.getRepository(), branchBId); if (ForkTree != null) { try (ObjectReader reader = repo.getRepository().newObjectReader()) { CanonicalTreeParser masterTreeIter = new CanonicalTreeParser(); masterTreeIter.reset(reader, masterTree); CanonicalTreeParser forkTreeIter = new CanonicalTreeParser(); forkTreeIter.reset(reader, ForkTree); try (DiffFormatter df = new DiffFormatter(new ByteArrayOutputStream())) { df.setRepository(repo.getRepository()); List<DiffEntry> entries = df.scan(forkTreeIter, masterTreeIter); entries.stream().forEach((entry) -> { diffs.add(entry); }); } } } } catch (IncorrectObjectTypeException ex) { Debug.reportError(ex.getMessage()); } catch (RevisionSyntaxException | IOException ex) { Debug.reportError(ex.getMessage()); } return diffs; }
| Find the last point in two branches where they where the same. | | @param repository the repository | @param base the name of the first ref | @param tip the name of the second ref | @return the merge point, or null if there is none. | @throws IOException if an IO error occurs | public static RevCommit findForkPoint(Repository repository, String base, String tip) throws IOException { try (RevWalk walk = new RevWalk(repository)) { RevCommit tipCommit = walk.lookupCommit(repository.resolve(tip)); RevCommit baseCommit = walk.lookupCommit(repository.resolve(base)); walk.setRevFilter(RevFilter.MERGE_BASE); walk.markStart(tipCommit); walk.markStart(baseCommit); RevCommit mergeBase = walk.next(); return mergeBase; } } public static String getFileNameFromDiff(DiffEntry entry) { String result; if (entry == null) { return ""; } if (entry.getChangeType() != DiffEntry.ChangeType.DELETE) { result = entry.getNewPath(); } else { result = entry.getOldPath(); } return result; }
| Return a diff from a list based on the file name. | @param entry | @param list | @return | public static DiffEntry getDiffFromList(DiffEntry entry, List<DiffEntry> list) { File entryFile = new File(getFileNameFromDiff(entry)); return getDiffFromList(entryFile, list); }
| Return a diff from a list based on the file name. | | @param entry | @param list | @return | @OnThread(Tag.Any) public static DiffEntry getDiffFromList(File entryFile, List<DiffEntry> list) { for (DiffEntry e : list) { File fe = new File(getFileNameFromDiff(e)); if (entryFile.equals(fe)) { return e; } } return null; }
| Checks if the repository is ahead and if behindCount = 0. | @param repo | @return | @throws IOException | public static boolean isAheadOnly(Git repo) throws IOException { BranchTrackingStatus bts = BranchTrackingStatus.of(repo.getRepository(), repo.getRepository().getBranch()); if (bts == null){ return false; } int aheadCount = bts.getAheadCount(); int behindCount = bts.getBehindCount(); return behindCount == 0 && aheadCount > 0; }
| Get the number of commits the repository is ahead the remote. | @param repo | @return | @throws IOException | public static int getAheadCount(Git repo) throws IOException, GitTreeException { BranchTrackingStatus bts = BranchTrackingStatus.of(repo.getRepository(), repo.getRepository().getBranch()); if (bts == null){ throw new GitTreeException(Config.getString("team.error.noHeadBranch")); } int aheadCount = bts.getAheadCount(); return aheadCount; }
| Checks if the repository is behind and if aheadCount = 0. | | @param repo | @return | @throws IOException | public static boolean isBehindOnly(Git repo) throws IOException { BranchTrackingStatus bts = BranchTrackingStatus.of(repo.getRepository(), repo.getRepository().getBranch()); if (bts == null){ return false; } int aheadCount = bts.getAheadCount(); int behindCount = bts.getBehindCount(); return aheadCount == 0 && behindCount > 0; }
| Get the number of commits the repository is behind the remote. | @param repo | @return | @throws IOException | public static int getBehindCount(Git repo) throws IOException, GitTreeException { BranchTrackingStatus bts = BranchTrackingStatus.of(repo.getRepository(), repo.getRepository().getBranch()); if (bts == null){ return 0; } int behindCount = bts.getBehindCount(); return behindCount; }
| Calculates the path of a file relative to the project. It also makes sure that the | separator is a Unix standard one, i.e. "/", as this is what jGit lib is expecting. |* see: http://bugs.bluej.org/browse/BLUEJ-1084 * * @param basePath The project path * @param file The file which relative path is needed * @return The relative path of the file to the project public static String getRelativeFileName(Path basePath, File file) { String fileName = basePath.relativize(file.toPath()).toString(); if (!File.separator.equals("/")) { fileName = fileName.replace(File.separator, "/"); } return fileName; } }
top, use, map, class GitUtilities

.   getTree
.   getDiffs
.   findForkPoint
.   getFileNameFromDiff
.   getDiffFromList
.   getDiffFromList
.   isAheadOnly
.   getAheadCount
.   isBehindOnly
.   getBehindCount
.   getRelativeFileName




266 neLoCode + 44 LoComm