diff options
4 files changed, 44 insertions, 4 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java index 5a3f98235b..f5470729db 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java @@ -45,6 +45,7 @@ import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.storage.pack.PackStatistics; import org.eclipse.jgit.transport.UploadPack.RequestPolicy; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; @@ -76,6 +77,8 @@ public class UploadPackTest { private TestRepository<InMemoryRepository> remote; + private PackStatistics stats; + @Before public void setUp() throws Exception { server = newRepo("server"); @@ -460,6 +463,7 @@ public class UploadPackTest { ByteArrayOutputStream recv = new ByteArrayOutputStream(); up.upload(send, recv, null); + stats = up.getStatistics(); return new ByteArrayInputStream(recv.toByteArray()); } @@ -1630,6 +1634,7 @@ public class UploadPackTest { .has(preparator.blobLowDepth.toObjectId())); assertFalse(client.getObjectDatabase() .has(preparator.blobHighDepth.toObjectId())); + assertEquals(1, stats.getTreesTraversed()); } @Test @@ -1651,6 +1656,7 @@ public class UploadPackTest { .has(preparator.blobLowDepth.toObjectId())); assertFalse(client.getObjectDatabase() .has(preparator.blobHighDepth.toObjectId())); + assertEquals(1, stats.getTreesTraversed()); } @Test @@ -1668,6 +1674,7 @@ public class UploadPackTest { .has(preparator.blobLowDepth.toObjectId())); assertFalse(client.getObjectDatabase() .has(preparator.blobHighDepth.toObjectId())); + assertEquals(2, stats.getTreesTraversed()); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java index c86afb08c3..c40094aef3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java @@ -2100,6 +2100,12 @@ public class PackWriter implements AutoCloseable { /** * Determines if the object should be omitted from the pack as a result of * its depth (probably because of the tree:<depth> filter). + * <p> + * Causes {@code walker} to skip traversing the current tree, which ought to + * have just started traversal, assuming this method is called as soon as a + * new depth is reached. + * <p> + * This method increments the {@code treesTraversed} statistic. * * @param obj * the object to check whether it should be omitted. @@ -2116,12 +2122,17 @@ public class PackWriter implements AutoCloseable { // A blob is considered one level deeper than the tree that contains it. if (obj.getType() == OBJ_BLOB) { treeDepth++; + } else { + stats.treesTraversed++; } - // TODO: Do not continue traversing the tree, since its children - // will also be too deep. - return filterSpec.getTreeDepthLimit() != -1 && - treeDepth > filterSpec.getTreeDepthLimit(); + if (filterSpec.getTreeDepthLimit() < 0 || + treeDepth <= filterSpec.getTreeDepthLimit()) { + return false; + } + + walker.skipTree(); + return true; } // Adds the given object as an object to be packed, first performing 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 3312b8aa81..af6040f9d5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java @@ -390,6 +390,17 @@ public class ObjectWalk extends RevWalk { } /** + * Skips the current tree such that {@link #nextObject()} does not return + * any objects inside it. This should be called right after + * {@link #nextObject()} returns the tree. + * + * @since 5.4 + */ + public void skipTree() { + currVisit.ptr = currVisit.buf.length; + } + + /** * Pop the next most recent object. * * @return next most recent object; null if traversal is over. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java index 68878e5a61..8a24234d86 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java @@ -266,6 +266,9 @@ public class PackStatistics { /** Time in ms spent writing the pack. */ public long timeWriting; + /** Number of trees traversed in the walk when writing the pack. */ + public long treesTraversed; + /** * Statistics about each object type in the pack (commits, tags, trees * and blobs.) @@ -586,6 +589,14 @@ public class PackStatistics { } /** + * @return number of trees traversed in the walk when writing the pack. + * @since 5.4 + */ + public long getTreesTraversed() { + return statistics.treesTraversed; + } + + /** * Get total time spent processing this pack. * * @return total time spent processing this pack. |