Creating an iterator with a path prefix permits a tree to be "mounted" at a different part of a repository, permitting more sophisticated merge strategies beyond just 1:1 path matching. Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx> --- .../jgit/treewalk/AbstractTreeIterator.java | 31 ++++++++++++++++++++ .../spearce/jgit/treewalk/CanonicalTreeParser.java | 28 ++++++++++++++++++ .../src/org/spearce/jgit/treewalk/TreeWalk.java | 2 +- 3 files changed, 60 insertions(+), 1 deletions(-) diff --git a/org.spearce.jgit/src/org/spearce/jgit/treewalk/AbstractTreeIterator.java b/org.spearce.jgit/src/org/spearce/jgit/treewalk/AbstractTreeIterator.java index 5226ab6..adfbb11 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/treewalk/AbstractTreeIterator.java +++ b/org.spearce.jgit/src/org/spearce/jgit/treewalk/AbstractTreeIterator.java @@ -170,6 +170,37 @@ protected AbstractTreeIterator(final String prefix) { } /** + * Create a new iterator with no parent and a prefix. + * <p> + * The prefix path supplied is inserted in front of all paths generated by + * this iterator. It is intended to be used when an iterator is being + * created for a subsection of an overall repository and needs to be + * combined with other iterators that are created to run over the entire + * repository namespace. + * + * @param prefix + * position of this iterator in the repository tree. The value + * may be null or the empty array to indicate the prefix is the + * root of the repository. A trailing slash ('/') is + * automatically appended if the prefix does not end in '/'. + */ + protected AbstractTreeIterator(final byte[] prefix) { + parent = null; + + if (prefix != null && prefix.length > 0) { + pathLen = prefix.length; + path = new byte[Math.max(DEFAULT_PATH_SIZE, pathLen + 1)]; + System.arraycopy(prefix, 0, path, 0, pathLen); + if (path[pathLen - 1] != '/') + path[pathLen++] = '/'; + pathOffset = pathLen; + } else { + path = new byte[DEFAULT_PATH_SIZE]; + pathOffset = 0; + } + } + + /** * Create an iterator for a subtree of an existing iterator. * * @param p diff --git a/org.spearce.jgit/src/org/spearce/jgit/treewalk/CanonicalTreeParser.java b/org.spearce.jgit/src/org/spearce/jgit/treewalk/CanonicalTreeParser.java index dcc53cd..3dac6dd 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/treewalk/CanonicalTreeParser.java +++ b/org.spearce.jgit/src/org/spearce/jgit/treewalk/CanonicalTreeParser.java @@ -62,6 +62,34 @@ public CanonicalTreeParser() { // Nothing necessary. } + /** + * Create a new parser for a tree appearing in a subset of a repository. + * + * @param prefix + * position of this iterator in the repository tree. The value + * may be null or the empty array to indicate the prefix is the + * root of the repository. A trailing slash ('/') is + * automatically appended if the prefix does not end in '/'. + * @param repo + * repository to load the tree data from. + * @param treeId + * identity of the tree being parsed; used only in exception + * messages if data corruption is found. + * @throws MissingObjectException + * the object supplied is not available from the repository. + * @throws IncorrectObjectTypeException + * the object supplied as an argument is not actually a tree and + * cannot be parsed as though it were a tree. + * @throws IOException + * a loose object or pack file could not be read. + */ + public CanonicalTreeParser(final byte[] prefix, final Repository repo, + final ObjectId treeId) throws IncorrectObjectTypeException, + IOException { + super(prefix); + reset(repo, treeId); + } + private CanonicalTreeParser(final CanonicalTreeParser p) { super(p); } diff --git a/org.spearce.jgit/src/org/spearce/jgit/treewalk/TreeWalk.java b/org.spearce.jgit/src/org/spearce/jgit/treewalk/TreeWalk.java index 3af3d09..b1cbd2d 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/treewalk/TreeWalk.java +++ b/org.spearce.jgit/src/org/spearce/jgit/treewalk/TreeWalk.java @@ -307,7 +307,7 @@ public void reset(final ObjectId[] ids) throws MissingObjectException, o = trees[i]; while (o.parent != null) o = o.parent; - if (o instanceof CanonicalTreeParser) { + if (o instanceof CanonicalTreeParser && o.pathOffset == 0) { o.matches = null; o.matchShift = 0; ((CanonicalTreeParser) o).reset(db, ids[i]); -- 1.6.0.2.706.g340fc -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html