diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java index 7bdc5bce4..e1ee1441d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java @@ -44,9 +44,13 @@ package org.eclipse.jgit.lib; import java.io.IOException; +import java.util.Collection; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.revwalk.ObjectWalk; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.storage.pack.ObjectReuseAsIs; /** @@ -173,6 +177,44 @@ public abstract class ObjectReader { return open(objectId, typeHint).getSize(); } + /** + * Advice from a {@link RevWalk} that a walk is starting from these roots. + * + * @param walk + * the revision pool that is using this reader. + * @param roots + * starting points of the revision walk. The starting points have + * their headers parsed, but might be missing bodies. + * @throws IOException + * the reader cannot initialize itself to support the walk. + */ + public void walkAdviceBeginCommits(RevWalk walk, Collection roots) + throws IOException { + // Do nothing by default, most readers don't want or need advice. + } + + /** + * Advice from an {@link ObjectWalk} that trees will be traversed. + * + * @param ow + * the object pool that is using this reader. + * @param min + * the first commit whose root tree will be read. + * @param max + * the last commit whose root tree will be read. + * @throws IOException + * the reader cannot initialize itself to support the walk. + */ + public void walkAdviceBeginTrees(ObjectWalk ow, RevCommit min, RevCommit max) + throws IOException { + // Do nothing by default, most readers don't want or need advice. + } + + /** Advice from that a walk is over. */ + public void walkAdviceEnd() { + // Do nothing by default, most readers don't want or need advice. + } + /** * Release any resources used by this reader. *

diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java index 76510ce38..735f7d602 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java @@ -137,6 +137,7 @@ class MergeBaseGenerator extends Generator { for (;;) { final RevCommit c = pending.next(); if (c == null) { + walker.reader.walkAdviceEnd(); walker.reader.release(); return null; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java index a6ecfe219..3df5a468f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java @@ -91,6 +91,10 @@ public class ObjectWalk extends RevWalk { private RevObject last; + private RevCommit firstCommit; + + private RevCommit lastCommit; + /** * Create a new revision and object walker for a given repository. * @@ -235,6 +239,9 @@ public class ObjectWalk extends RevWalk { } continue; } + if (firstCommit == null) + firstCommit = r; + lastCommit = r; pendingObjects.add(r.getTree()); return r; } @@ -295,11 +302,19 @@ public class ObjectWalk extends RevWalk { treeWalk = treeWalk.next(); } + if (firstCommit != null) { + reader.walkAdviceBeginTrees(this, firstCommit, lastCommit); + firstCommit = null; + lastCommit = null; + } + last = null; for (;;) { final RevObject o = pendingObjects.next(); - if (o == null) + if (o == null) { + reader.walkAdviceEnd(); return null; + } if ((o.flags & SEEN) != 0) continue; o.flags |= SEEN; @@ -403,6 +418,8 @@ public class ObjectWalk extends RevWalk { treeWalk = new CanonicalTreeParser(); currentTree = null; last = null; + firstCommit = null; + lastCommit = null; } @Override @@ -412,6 +429,8 @@ public class ObjectWalk extends RevWalk { treeWalk = new CanonicalTreeParser(); currentTree = null; last = null; + firstCommit = null; + lastCommit = null; } private void addObject(final RevObject o) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PendingGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PendingGenerator.java index 0e2bb9832..ec7069b4d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PendingGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PendingGenerator.java @@ -128,7 +128,9 @@ class PendingGenerator extends Generator { for (;;) { final RevCommit c = pending.next(); if (c == null) { - walker.reader.release(); + walker.reader.walkAdviceEnd(); + if (!(walker instanceof ObjectWalk)) + walker.reader.release(); return null; } @@ -174,6 +176,7 @@ class PendingGenerator extends Generator { c.disposeBody(); } } catch (StopWalkException swe) { + walker.reader.walkAdviceEnd(); walker.reader.release(); pending.clear(); return null; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java index 7406bb60c..5f8fd5c8a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java @@ -172,7 +172,7 @@ public class RevWalk implements Iterable { int carryFlags = UNINTERESTING; - private final ArrayList roots; + final ArrayList roots; AbstractRevQueue queue; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java index 5e778a416..fbff02778 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java @@ -85,6 +85,8 @@ class StartGenerator extends Generator { final TreeFilter tf = w.getTreeFilter(); AbstractRevQueue q = walker.queue; + w.reader.walkAdviceBeginCommits(w, w.roots); + if (rf == RevFilter.MERGE_BASE) { // Computing for merge bases is a special case and does not // use the bulk of the generator pipeline.