Merge changes from topics "jgit-reachability", "reachability-2"
* changes:
VisibilityChecker: Remove topoSort argument
VisibilityCache: Use jgit's ReachabilityChecker
diff --git a/java/com/google/gitiles/GitilesFilter.java b/java/com/google/gitiles/GitilesFilter.java
index 254fe22..79dcc4c 100644
--- a/java/com/google/gitiles/GitilesFilter.java
+++ b/java/com/google/gitiles/GitilesFilter.java
@@ -383,9 +383,9 @@
if (visibilityCache == null) {
if (config.getSubsections("cache").contains("visibility")) {
visibilityCache =
- new VisibilityCache(false, ConfigUtil.getCacheBuilder(config, "visibility"));
+ new VisibilityCache(ConfigUtil.getCacheBuilder(config, "visibility"));
} else {
- visibilityCache = new VisibilityCache(false);
+ visibilityCache = new VisibilityCache();
}
}
}
diff --git a/java/com/google/gitiles/VisibilityCache.java b/java/com/google/gitiles/VisibilityCache.java
index fe1c07e..1c6b785 100644
--- a/java/com/google/gitiles/VisibilityCache.java
+++ b/java/com/google/gitiles/VisibilityCache.java
@@ -89,16 +89,16 @@
return CacheBuilder.newBuilder().maximumSize(1 << 10).expireAfterWrite(30, TimeUnit.MINUTES);
}
- public VisibilityCache(boolean topoSort) {
- this(topoSort, defaultBuilder());
+ public VisibilityCache() {
+ this(new VisibilityChecker(), defaultBuilder());
}
- public VisibilityCache(boolean topoSort, CacheBuilder<Object, Object> builder) {
- this(new VisibilityChecker(topoSort), builder);
+ public VisibilityCache(CacheBuilder<Object, Object> builder) {
+ this(new VisibilityChecker(), builder);
}
/**
- * Use the constructors with a boolean parameter (e.g. {@link #VisibilityCache(boolean)}). The
+ * Use the constructors with a boolean parameter (e.g. {@link #VisibilityCache()}). The
* default visibility checker should cover all common use cases.
*
* <p>This constructor is useful to use a checker with additional logging or metrics collection,
@@ -109,7 +109,7 @@
}
/**
- * Use the constructors with a boolean parameter (e.g. {@link #VisibilityCache(boolean)}). The
+ * Use the constructors with a boolean parameter (e.g. {@link #VisibilityCache()}). The
* default visibility checker should cover all common use cases.
*
* <p>This constructor is useful to use a checker with additional logging or metrics collection,
diff --git a/java/com/google/gitiles/VisibilityChecker.java b/java/com/google/gitiles/VisibilityChecker.java
index ccd5cf1..899d1f1 100644
--- a/java/com/google/gitiles/VisibilityChecker.java
+++ b/java/com/google/gitiles/VisibilityChecker.java
@@ -42,6 +42,7 @@
*/
package com.google.gitiles;
+import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.util.Collection;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
@@ -49,7 +50,6 @@
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevWalk;
/**
@@ -59,16 +59,6 @@
*/
public class VisibilityChecker {
- private final boolean topoSort;
-
- /**
- * @param topoSort whether to use a more thorough reachability check by sorting in topological
- * order
- */
- public VisibilityChecker(boolean topoSort) {
- this.topoSort = topoSort;
- }
-
/**
* Check if any of the refs in {@code refDb} points to the object {@code id}.
*
@@ -90,7 +80,7 @@
* @param walk The walk to use for the reachability check
* @param commit The starting commit. It *MUST* come from the walk in use
* @param starters visible commits. Anything reachable from these commits is visible. Missing ids
- * or ids pointing to wrong kind of objects are ignored.
+ * or ids referring to other kinds of objects are ignored.
* @return true if we can get to {@code commit} from the {@code starters}
* @throws IOException a pack file or loose object could not be read
*/
@@ -101,28 +91,29 @@
return false;
}
- walk.reset();
- if (topoSort) {
- walk.sort(RevSort.TOPO);
+ ImmutableList<RevCommit> startCommits = objectIdsToCommits(walk, starters);
+ if (startCommits.isEmpty()) {
+ return false;
}
- walk.markStart(commit);
- for (ObjectId id : starters) {
- markUninteresting(walk, id);
- }
- // If the commit is reachable from any given tip, it will appear to be
- // uninteresting to the RevWalk and no output will be produced.
- return walk.next() == null;
+ return !walk.createReachabilityChecker()
+ .areAllReachable(ImmutableList.of(commit), startCommits)
+ .isPresent();
}
- private static void markUninteresting(RevWalk walk, ObjectId id) throws IOException {
- if (id == null) {
- return;
+ private static ImmutableList<RevCommit> objectIdsToCommits(RevWalk walk, Collection<ObjectId> ids)
+ throws IOException {
+ ImmutableList.Builder<RevCommit> commits = ImmutableList.builder();
+ for (ObjectId id : ids) {
+ try {
+ commits.add(walk.parseCommit(id));
+ } catch (MissingObjectException e) {
+ // TODO(ifrade): ResolveParser has already checked that the object exists in the repo.
+ // Report as AssertionError.
+ } catch (IncorrectObjectTypeException e) {
+ // Ignore, doesn't affect commit reachability
+ }
}
- try {
- walk.markUninteresting(walk.parseCommit(id));
- } catch (IncorrectObjectTypeException | MissingObjectException e) {
- // Do nothing, doesn't affect reachability.
- }
+ return commits.build();
}
}
diff --git a/javatests/com/google/gitiles/RevisionParserTest.java b/javatests/com/google/gitiles/RevisionParserTest.java
index b2c88ea..16e76a7 100644
--- a/javatests/com/google/gitiles/RevisionParserTest.java
+++ b/javatests/com/google/gitiles/RevisionParserTest.java
@@ -46,7 +46,7 @@
new RevisionParser(
repo.getRepository(),
new TestGitilesAccess(repo.getRepository()).forRequest(null),
- new VisibilityCache(false, CacheBuilder.newBuilder().maximumSize(0)));
+ new VisibilityCache(CacheBuilder.newBuilder().maximumSize(0)));
}
@Test
diff --git a/javatests/com/google/gitiles/TestViewFilter.java b/javatests/com/google/gitiles/TestViewFilter.java
index 68acffb..4f67efc 100644
--- a/javatests/com/google/gitiles/TestViewFilter.java
+++ b/javatests/com/google/gitiles/TestViewFilter.java
@@ -65,7 +65,7 @@
new ViewFilter(
new TestGitilesAccess(repo.getRepository()),
TestGitilesUrls.URLS,
- new VisibilityCache(false));
+ new VisibilityCache());
MetaFilter mf = new MetaFilter();
for (Pattern p : ImmutableList.of(ROOT_REGEX, REPO_REGEX, REPO_PATH_REGEX)) {
diff --git a/javatests/com/google/gitiles/VisibilityCacheTest.java b/javatests/com/google/gitiles/VisibilityCacheTest.java
index bcc2b40..92ea04b 100644
--- a/javatests/com/google/gitiles/VisibilityCacheTest.java
+++ b/javatests/com/google/gitiles/VisibilityCacheTest.java
@@ -108,7 +108,7 @@
git.update("refs/tags/v0.1", commitA);
}
- visibilityCache = new VisibilityCache(true);
+ visibilityCache = new VisibilityCache();
walk = new RevWalk(repo);
walk.setRetainBody(false);
}
diff --git a/javatests/com/google/gitiles/VisibilityCheckerTest.java b/javatests/com/google/gitiles/VisibilityCheckerTest.java
index 3171459..5470e52 100644
--- a/javatests/com/google/gitiles/VisibilityCheckerTest.java
+++ b/javatests/com/google/gitiles/VisibilityCheckerTest.java
@@ -89,7 +89,7 @@
git.update("refs/tags/v0.1", commitA);
}
- visibilityChecker = new VisibilityChecker(true);
+ visibilityChecker = new VisibilityChecker();
walk = new RevWalk(repo);
walk.setRetainBody(false);
}