summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java7
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java19
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java11
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java11
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.