org.gitective.core.TreeUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gitective-core Show documentation
Show all versions of gitective-core Show documentation
fabric8 gitective core library
The newest version!
/*
* Copyright (c) 2011 Kevin Sawicki
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
package org.gitective.core;
import static org.eclipse.jgit.lib.FileMode.TYPE_MASK;
import static org.eclipse.jgit.lib.FileMode.TYPE_TREE;
import static org.eclipse.jgit.treewalk.filter.TreeFilter.ANY_DIFF;
import java.io.IOException;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.MutableObjectId;
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.EmptyTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
/**
* Utilities for dealing with Git trees.
*/
public abstract class TreeUtils {
/**
* Interface for visiting elements in a tree
*/
public static interface ITreeVisitor {
/**
* Visit the given element
*
* @param mode
* mode of current entry
* @param path
* parent path of entry, null for root entries
* @param name
* name of current entry
* @param id
* id of current entry
* @return true to continue, false to abort
*/
boolean accept(FileMode mode, String path, String name, AnyObjectId id);
}
/**
* Get the tree associated with the given commit.
*
* @param walk
* @param commit
* @return tree
* @throws IOException
*/
protected static RevTree getTree(final RevWalk walk, final RevCommit commit)
throws IOException {
final RevTree tree = commit.getTree();
if (tree != null)
return tree;
walk.parseHeaders(commit);
return commit.getTree();
}
/**
* Create a tree walk with the commit's parents.
*
* @param reader
* @param rWalk
* @param commit
* @return tree walk
* @throws IOException
*/
protected static TreeWalk withParents(final ObjectReader reader,
final RevWalk rWalk, final RevCommit commit) throws IOException {
final TreeWalk walk = new TreeWalk(reader);
final int parentCount = commit.getParentCount();
switch (parentCount) {
case 0:
walk.addTree(new EmptyTreeIterator());
break;
case 1:
walk.addTree(getTree(rWalk, commit.getParent(0)));
break;
default:
final RevCommit[] parents = commit.getParents();
for (int i = 0; i < parentCount; i++)
walk.addTree(getTree(rWalk, parents[i]));
}
walk.addTree(getTree(rWalk, commit));
return walk;
}
/**
* Create a tree walk with all the trees from the given commit's parents.
*
* @param repository
* @param commitId
* @return tree walk
*/
public static TreeWalk withParents(final Repository repository,
final AnyObjectId commitId) {
if (repository == null)
throw new IllegalArgumentException(
Assert.formatNotNull("Repository"));
if (commitId == null)
throw new IllegalArgumentException(
Assert.formatNotNull("Commit id"));
final ObjectReader reader = repository.newObjectReader();
final RevWalk walk = new RevWalk(reader);
try {
return withParents(reader, walk, walk.parseCommit(commitId));
} catch (IOException e) {
walk.close();
throw new GitException(e, repository);
}
}
/**
* Create a tree walk with all the trees from the given revision's commit
* parents.
*
* @param repository
* @param revision
* @return tree walk
*/
public static TreeWalk withParents(final Repository repository,
final String revision) {
if (repository == null)
throw new IllegalArgumentException(
Assert.formatNotNull("Repository"));
if (revision == null)
throw new IllegalArgumentException(Assert.formatNotNull("Revision"));
if (revision.length() == 0)
throw new IllegalArgumentException(
Assert.formatNotEmpty("Revision"));
final ObjectId commit = CommitUtils.strictResolve(repository, revision);
final ObjectReader reader = repository.newObjectReader();
final RevWalk walk = new RevWalk(reader);
try {
return withParents(reader, walk, walk.parseCommit(commit));
} catch (IOException e) {
walk.close();
throw new GitException(e, repository);
}
}
/**
* Create a tree walk with all the trees from the given commit's parents.
*
* @param walk
* @param commit
* @return tree walk
*/
public static TreeWalk withParents(final RevWalk walk,
final RevCommit commit) {
if (walk == null)
throw new IllegalArgumentException(Assert.formatNotNull("Walk"));
if (commit == null)
throw new IllegalArgumentException(Assert.formatNotNull("Commit"));
try {
return withParents(walk.getObjectReader(), walk, commit);
} catch (IOException e) {
throw new GitException(e, null);
}
}
/**
* Create a tree walk configured to diff the given commit against all the
* parent commits.
*
* @param repository
* @param commitId
* @return tree walk
*/
public static TreeWalk diffWithParents(final Repository repository,
final AnyObjectId commitId) {
final TreeWalk walk = withParents(repository, commitId);
walk.setFilter(ANY_DIFF);
return walk;
}
/**
* Create a tree walk configured to diff the given commit against all the
* parent commits.
*
* @param walk
* @param commit
* @return tree walk
*/
public static TreeWalk diffWithParents(final RevWalk walk,
final RevCommit commit) {
final TreeWalk treeWalk = withParents(walk, commit);
treeWalk.setFilter(ANY_DIFF);
return treeWalk;
}
/**
* Create a tree walk configured to diff the given revision against all the
* parent commits.
*
* @param repository
* @param revision
* @return tree walk
*/
public static TreeWalk diffWithParents(final Repository repository,
final String revision) {
final TreeWalk walk = withParents(repository, revision);
walk.setFilter(ANY_DIFF);
return walk;
}
/**
* Create a tree walk configured with the given commit revisions
*
* @param repository
* @param revisions
* @return tree walk
*/
public static TreeWalk withCommits(final Repository repository,
final String... revisions) {
if (repository == null)
throw new IllegalArgumentException(
Assert.formatNotNull("Repository"));
if (revisions == null)
throw new IllegalArgumentException(
Assert.formatNotNull("Revisions"));
if (revisions.length == 0)
throw new IllegalArgumentException(
Assert.formatNotEmpty("Revisions"));
final TreeWalk walk = new TreeWalk(repository);
try {
for (String revision : revisions)
walk.addTree(CommitUtils.getCommit(repository, revision)
.getTree());
} catch (IOException e) {
throw new GitException(e, repository);
}
return walk;
}
/**
* Create a tree walk configured with the given commits
*
* @param repository
* @param commits
* @return tree walk
*/
public static TreeWalk withCommits(final Repository repository,
final ObjectId... commits) {
if (repository == null)
throw new IllegalArgumentException(
Assert.formatNotNull("Repository"));
if (commits == null)
throw new IllegalArgumentException(Assert.formatNotNull("Commits"));
if (commits.length == 0)
throw new IllegalArgumentException(Assert.formatNotEmpty("Commits"));
final TreeWalk walk = new TreeWalk(repository);
try {
for (ObjectId commit : commits)
walk.addTree(CommitUtils.getCommit(repository, commit)
.getTree());
} catch (IOException e) {
throw new GitException(e, repository);
}
return walk;
}
/**
* Create a tree walk configured to diff the given commits
*
* @param repository
* @param commits
* @return tree walk
*/
public static TreeWalk diffWithCommits(final Repository repository,
final ObjectId... commits) {
final TreeWalk walk = withCommits(repository, commits);
walk.setFilter(ANY_DIFF);
return walk;
}
/**
* Create a tree walk configured to diff the given commit revisions
*
* @param repository
* @param revisions
* @return tree walk
*/
public static TreeWalk diffWithCommits(final Repository repository,
final String... revisions) {
final TreeWalk walk = withCommits(repository, revisions);
walk.setFilter(ANY_DIFF);
return walk;
}
/**
* Get the id of the tree at the path in the given commit.
*
* @param repository
* @param commit
* @param path
* @return tree id, null if not present
*/
protected static ObjectId lookupId(final Repository repository,
final RevCommit commit, final String path) {
final TreeWalk walk;
try {
walk = TreeWalk.forPath(repository, path, commit.getTree());
} catch (IOException e) {
throw new GitException(e, repository);
}
if (walk == null)
return null;
if ((walk.getRawMode(0) & TYPE_MASK) != TYPE_TREE)
return null;
return walk.getObjectId(0);
}
/**
* Get the id of the tree at the path in the given commit
*
* @param repository
* @param commitId
* @param path
* @return tree id or null if no tree id at path
*/
public static ObjectId getId(final Repository repository,
final ObjectId commitId, final String path) {
if (repository == null)
throw new IllegalArgumentException(
Assert.formatNotNull("Repository"));
if (commitId == null)
throw new IllegalArgumentException(
Assert.formatNotNull("Commit Id"));
if (path == null)
throw new IllegalArgumentException(Assert.formatNotNull("Path"));
if (path.length() == 0)
throw new IllegalArgumentException(Assert.formatNotNull("Path"));
final RevCommit commit = CommitUtils.parse(repository, commitId);
return lookupId(repository, commit, path);
}
/**
* Get the id of the tree at the path in the given revision
*
* @param repository
* @param revision
* @param path
* @return tree id or null if no tree id at path
*/
public static ObjectId getId(final Repository repository,
final String revision, final String path) {
if (repository == null)
throw new IllegalArgumentException(
Assert.formatNotNull("Repository"));
if (revision == null)
throw new IllegalArgumentException(Assert.formatNotNull("Revision"));
if (revision.length() == 0)
throw new IllegalArgumentException(
Assert.formatNotEmpty("Revision"));
if (path == null)
throw new IllegalArgumentException(Assert.formatNotNull("Path"));
if (path.length() == 0)
throw new IllegalArgumentException(Assert.formatNotNull("Path"));
final RevCommit commit = CommitUtils.parse(repository,
CommitUtils.strictResolve(repository, revision));
return lookupId(repository, commit, path);
}
/**
* Visit entries in the given tree
*
* @param repository
* @param treeId
* @param visitor
* @return true if fully completed, false if terminated early
*/
public static boolean visit(final Repository repository,
final ObjectId treeId, final ITreeVisitor visitor) {
if (repository == null)
throw new IllegalArgumentException(
Assert.formatNotNull("Repository"));
if (treeId == null)
throw new IllegalArgumentException(Assert.formatNotNull("Tree Id"));
if (visitor == null)
throw new IllegalArgumentException(Assert.formatNotNull("Visitor"));
final TreeWalk walk = new TreeWalk(repository);
walk.setPostOrderTraversal(true);
final MutableObjectId id = new MutableObjectId();
try {
walk.addTree(treeId);
if (!visit(repository, walk, id, null, visitor))
return false;
} catch (IOException e) {
throw new GitException(e, repository);
} finally {
walk.close();
}
return true;
}
private static boolean visit(final Repository repository,
final TreeWalk walk, final MutableObjectId id, final String path,
final ITreeVisitor visitor) throws IOException {
while (walk.next()) {
if (walk.isPostChildren())
break;
if (walk.isSubtree()) {
final String subTreePath = walk.getPathString();
walk.enterSubtree();
if (!visit(repository, walk, id, subTreePath, visitor))
return false;
}
walk.getObjectId(id, 0);
if (!visitor.accept(walk.getFileMode(0), path,
walk.getNameString(), id))
return false;
}
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy