LogServlet: enable Commit Graph and Bloom Filter serving
The current setup of LogServlet does not permit Commit Graph and Bloom
Filter serving due to their RevWalk setup does not disable RetainBody
flag and does not accept the intended ChangedPathTreeFilter.
Incorporating RetainBody disable and ChangedPathTreeFilter into RevWalk
setup.
Change-Id: I5e2d7f00df67708c41e2509d5a12e3661a0cecd9
Signed-off-by: Xing Huang <[email protected]>
diff --git a/java/com/google/gitiles/LogServlet.java b/java/com/google/gitiles/LogServlet.java
index 9a66ef8..71f7384 100644
--- a/java/com/google/gitiles/LogServlet.java
+++ b/java/com/google/gitiles/LogServlet.java
@@ -57,9 +57,7 @@
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.filter.AndRevFilter;
import org.eclipse.jgit.revwalk.filter.RevFilter;
-import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
-import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
-import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.eclipse.jgit.treewalk.filter.ChangedPathTreeFilter;
import org.eclipse.jgit.util.StringUtils;
/** Serves an HTML page with a shortlog for commits and paths. */
@@ -162,6 +160,10 @@
CommitJsonData.Log result = new CommitJsonData.Log();
List<CommitJsonData.Commit> entries = Lists.newArrayListWithCapacity(paginator.getLimit());
for (RevCommit c : paginator) {
+ RevWalk walk = paginator.getWalk();
+ if (!walk.isRetainBody()) {
+ walk.parseBody(c);
+ }
entries.add(new CommitJsonData().toJsonData(req, paginator.getWalk(), c, fs, df));
}
result.log = entries;
@@ -249,6 +251,7 @@
}
setTreeFilter(walk, view, access);
setRevFilter(walk, view);
+ walk.setRetainBody(false);
return walk;
}
@@ -291,8 +294,7 @@
if (follow) {
walk.setTreeFilter(FollowFilter.create(path, access.getConfig().get(DiffConfig.KEY)));
} else {
- walk.setTreeFilter(
- AndTreeFilter.create(PathFilterGroup.createFromStrings(path), TreeFilter.ANY_DIFF));
+ walk.setTreeFilter(ChangedPathTreeFilter.create(path));
}
}
diff --git a/java/com/google/gitiles/LogSoyData.java b/java/com/google/gitiles/LogSoyData.java
index b3afa04..ca59ac4 100644
--- a/java/com/google/gitiles/LogSoyData.java
+++ b/java/com/google/gitiles/LogSoyData.java
@@ -34,6 +34,7 @@
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
public class LogSoyData {
private static final ImmutableSet<Field> FIELDS =
@@ -101,6 +102,10 @@
renderer.newRenderer("com.google.gitiles.templates.LogDetail.logEntryWrapper");
boolean renderedEntries = false;
for (RevCommit c : paginator) {
+ RevWalk walk = paginator.getWalk();
+ if (!walk.isRetainBody()) {
+ walk.parseBody(c);
+ }
renderHtml(entryRenderer.setData(toEntrySoyData(paginator, c, df)), writer);
renderedEntries = true;
}
diff --git a/javatests/com/google/gitiles/BUILD b/javatests/com/google/gitiles/BUILD
index cf5572f..e7576a5 100644
--- a/javatests/com/google/gitiles/BUILD
+++ b/javatests/com/google/gitiles/BUILD
@@ -42,6 +42,7 @@
"//java/com/google/gitiles:servlet",
":testutil",
"//lib:servlet-api",
+ "//lib:commons-codec",
"//lib/truth",
"//lib:jgit-junit",
"//lib/junit",
diff --git a/javatests/com/google/gitiles/LogServletTest.java b/javatests/com/google/gitiles/LogServletTest.java
index d875e0e..0072e9c 100644
--- a/javatests/com/google/gitiles/LogServletTest.java
+++ b/javatests/com/google/gitiles/LogServletTest.java
@@ -22,7 +22,12 @@
import com.google.gitiles.DateFormatter.Format;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
+import org.eclipse.jgit.internal.storage.commitgraph.ChangedPathFilter;
+import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -237,6 +242,95 @@
testPrettyHtmlOutput("fuller", /* shouldShowAuthor= */ true, /* shouldShowCommitter= */ true);
}
+ @Test
+ public void logJsonWithCommitGraphAndChangedPaths_optimizationsPresent() throws Exception {
+ String contents1 = "contents1";
+ String contents2 = "contents2";
+
+ RevCommit c1 = repo.branch("master").commit().add("foo", contents1).create();
+ RevCommit c2 = repo.branch("master").commit().rm("foo").add("foo", contents2).create();
+
+ enableAndWriteCommitGraph();
+
+ Log response = buildJson(LOG, "/repo/+log/master/foo");
+ assertThat(response.log).hasSize(2);
+ verifyJsonCommit(response.log.get(0), c2);
+ verifyJsonCommit(response.log.get(1), c1);
+
+ RevWalk rw = new RevWalk(repo.getRepository());
+ ChangedPathFilter filter1 = rw.parseCommit(c1.toObjectId()).getChangedPathFilter(rw);
+ assertThat(filter1).isNotNull();
+ ChangedPathFilter filter2 = rw.parseCommit(c2.toObjectId()).getChangedPathFilter(rw);
+ assertThat(filter2).isNotNull();
+ }
+
+ @Test
+ public void logHttpWithCommitGraphAndChangedPaths_optimizationsPresent() throws Exception {
+ String contents1 = "contents1";
+ String contents2 = "contents2";
+
+ RevCommit c1 = repo.branch("master").commit().add("foo", contents1).create();
+ RevCommit c2 = repo.branch("master").commit().rm("foo").add("foo", contents2).create();
+
+ enableAndWriteCommitGraph();
+
+ String path = "/repo/+log/refs/heads/master/foo";
+ FakeHttpServletResponse res = buildResponse(path, "format=html" + "&n=" + 2, SC_OK);
+
+ assertThat(res.getActualBodyString()).contains(c1.toObjectId().name());
+ assertThat(res.getActualBodyString()).contains(c2.toObjectId().name());
+
+ RevWalk rw = new RevWalk(repo.getRepository());
+ ChangedPathFilter filter1 = rw.parseCommit(c1.toObjectId()).getChangedPathFilter(rw);
+ assertThat(filter1).isNotNull();
+ ChangedPathFilter filter2 = rw.parseCommit(c2.toObjectId()).getChangedPathFilter(rw);
+ assertThat(filter2).isNotNull();
+ }
+
+ @Test
+ public void followJsonWithCommitGraphAndChangedPaths_optimizationsPresent() throws Exception {
+ String contents = "contents";
+
+ RevCommit c1 = repo.branch("master").commit().add("foo", contents).create();
+ RevCommit c2 = repo.branch("master").commit().rm("foo").add("bar", contents).create();
+
+ enableAndWriteCommitGraph();
+
+ Log response = buildJson(LOG, "/repo/+log/master/bar", "follow=1");
+ assertThat(response.log).hasSize(2);
+ verifyJsonCommit(response.log.get(0), c2);
+ verifyJsonCommit(response.log.get(1), c1);
+
+ RevWalk rw = new RevWalk(repo.getRepository());
+ ChangedPathFilter filter1 = rw.parseCommit(c1.toObjectId()).getChangedPathFilter(rw);
+ assertThat(filter1).isNotNull();
+ ChangedPathFilter filter2 = rw.parseCommit(c2.toObjectId()).getChangedPathFilter(rw);
+ assertThat(filter2).isNotNull();
+ }
+
+ @Test
+ public void followHttpWithCommitGraphAndChangedPaths_optimizationsPresent() throws Exception {
+ String contents = "contents";
+
+ RevCommit c1 = repo.branch("master").commit().add("foo", contents).create();
+ RevCommit c2 = repo.branch("master").commit().rm("foo").add("bar", contents).create();
+
+ enableAndWriteCommitGraph();
+
+ String path = "/repo/+log/refs/heads/master/bar";
+ FakeHttpServletResponse res =
+ buildResponse(path, "format=html" + "&n=" + 2 + "follow=1", SC_OK);
+
+ assertThat(res.getActualBodyString()).contains(c1.toObjectId().name());
+ assertThat(res.getActualBodyString()).contains(c2.toObjectId().name());
+
+ RevWalk rw = new RevWalk(repo.getRepository());
+ ChangedPathFilter filter1 = rw.parseCommit(c1.toObjectId()).getChangedPathFilter(rw);
+ assertThat(filter1).isNotNull();
+ ChangedPathFilter filter2 = rw.parseCommit(c2.toObjectId()).getChangedPathFilter(rw);
+ assertThat(filter2).isNotNull();
+ }
+
private void testPrettyHtmlOutput(
String prettyType, boolean shouldShowAuthor, boolean shouldShowCommitter) throws Exception {
RevCommit parent = repo.branch(MAIN).commit().add("foo", "contents").create();
@@ -262,4 +356,20 @@
assertThat(res.getActualBodyString()).doesNotContain(COMMITTER_METADATA_ELEMENT);
}
}
+
+ void enableAndWriteCommitGraph() throws Exception {
+ repo.getRepository()
+ .getConfig()
+ .setBoolean(
+ ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_COMMIT_GRAPH, true);
+ repo.getRepository()
+ .getConfig()
+ .setBoolean(
+ ConfigConstants.CONFIG_COMMIT_GRAPH_SECTION,
+ null,
+ ConfigConstants.CONFIG_KEY_READ_CHANGED_PATHS,
+ true);
+ DfsGarbageCollector gc = new DfsGarbageCollector(repo.getRepository());
+ gc.setWriteCommitGraph(true).setWriteBloomFilter(true).pack(NullProgressMonitor.INSTANCE);
+ }
}