aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java113
1 files changed, 81 insertions, 32 deletions
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 3737c6b67b..41f98bad84 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
@@ -19,8 +19,14 @@ import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.
+Optional;
+import java.util.Set;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.annotations.Nullable;
@@ -30,9 +36,9 @@ import org.eclipse.jgit.errors.LargeObjectException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.RevWalkException;
import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.AsyncObjectLoaderQueue;
-import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.MutableObjectId;
import org.eclipse.jgit.lib.NullProgressMonitor;
@@ -220,7 +226,6 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
/**
* Create a new revision walker for a given repository.
- * <p>
*
* @param or
* the reader the walker will obtain data from. The reader is not
@@ -236,7 +241,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
idBuffer = new MutableObjectId();
objects = new ObjectIdOwnerMap<>();
roots = new ArrayList<>();
- queue = new DateRevQueue(false);
+ queue = newDateRevQueue(false);
pending = new StartGenerator(this);
sorting = EnumSet.of(RevSort.NONE);
filter = RevFilter.ALL;
@@ -245,6 +250,30 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
commitGraph = null;
}
+ static AbstractRevQueue newDateRevQueue(boolean firstParent) {
+ if(usePriorityQueue()) {
+ return new DateRevPriorityQueue(firstParent);
+ }
+
+ return new DateRevQueue(firstParent);
+ }
+
+ static DateRevQueue newDateRevQueue(Generator g) throws IOException {
+ if(usePriorityQueue()) {
+ return new DateRevPriorityQueue(g);
+ }
+
+ return new DateRevQueue(g);
+ }
+
+ @SuppressWarnings("boxing")
+ private static boolean usePriorityQueue() {
+ return Optional
+ .ofNullable(System.getProperty("REVWALK_USE_PRIORITY_QUEUE")) //$NON-NLS-1$
+ .map(Boolean::parseBoolean)
+ .orElse(false);
+ }
+
/**
* Get the reader this walker is using to load objects.
*
@@ -255,23 +284,6 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
}
/**
- * Get a reachability checker for commits over this revwalk.
- *
- * @return the most efficient reachability checker for this repository.
- * @throws IOException
- * if it cannot open any of the underlying indices.
- *
- * @since 5.4
- * @deprecated use {@code ObjectReader#createReachabilityChecker(RevWalk)}
- * instead.
- */
- @Deprecated
- public final ReachabilityChecker createReachabilityChecker()
- throws IOException {
- return reader.createReachabilityChecker(this);
- }
-
- /**
* {@inheritDoc}
* <p>
* Release any resources used by this walker's reader.
@@ -454,7 +466,6 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
* <p>
* A commit is merged into a ref if we can find a path of commits that leads
* from that specific ref and ends at <code>commit</code>.
- * <p>
*
* @param commit
* commit the caller thinks is reachable from <code>refs</code>.
@@ -476,7 +487,6 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
* <p>
* A commit is merged into a ref if we can find a path of commits that leads
* from that specific ref and ends at <code>commit</code>.
- * <p>
*
* @param commit
* commit the caller thinks is reachable from <code>refs</code>.
@@ -518,6 +528,27 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
}
/**
+ * Determine if a <code>commit</code> is merged into any of the given
+ * <code>revs</code>.
+ *
+ * @param commit
+ * commit the caller thinks is reachable from <code>revs</code>.
+ * @param revs
+ * commits to start iteration from, and which is most likely a
+ * descendant (child) of <code>commit</code>.
+ * @return true if commit is merged into any of the revs; false otherwise.
+ * @throws java.io.IOException
+ * a pack file or loose object could not be read.
+ * @since 6.10.1
+ */
+ public boolean isMergedIntoAnyCommit(RevCommit commit, Collection<RevCommit> revs)
+ throws IOException {
+ return getCommitsMergedInto(commit, revs,
+ GetMergedIntoStrategy.RETURN_ON_FIRST_FOUND,
+ NullProgressMonitor.INSTANCE).size() > 0;
+ }
+
+ /**
* Determine if a <code>commit</code> is merged into all of the given
* <code>refs</code>.
*
@@ -540,7 +571,26 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
private List<Ref> getMergedInto(RevCommit needle, Collection<Ref> haystacks,
Enum returnStrategy, ProgressMonitor monitor) throws IOException {
+ Map<RevCommit, List<Ref>> refsByCommit = new HashMap<>();
+ for (Ref r : haystacks) {
+ RevObject o = peel(parseAny(r.getObjectId()));
+ if (!(o instanceof RevCommit)) {
+ continue;
+ }
+ refsByCommit.computeIfAbsent((RevCommit) o, c -> new ArrayList<>()).add(r);
+ }
+ monitor.update(1);
List<Ref> result = new ArrayList<>();
+ for (RevCommit c : getCommitsMergedInto(needle, refsByCommit.keySet(),
+ returnStrategy, monitor)) {
+ result.addAll(refsByCommit.get(c));
+ }
+ return result;
+ }
+
+ private Set<RevCommit> getCommitsMergedInto(RevCommit needle, Collection<RevCommit> haystacks,
+ Enum returnStrategy, ProgressMonitor monitor) throws IOException {
+ Set<RevCommit> result = new HashSet<>();
List<RevCommit> uninteresting = new ArrayList<>();
List<RevCommit> marked = new ArrayList<>();
RevFilter oldRF = filter;
@@ -556,16 +606,11 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
needle.parseHeaders(this);
}
int cutoff = needle.getGeneration();
- for (Ref r : haystacks) {
+ for (RevCommit c : haystacks) {
if (monitor.isCancelled()) {
return result;
}
monitor.update(1);
- RevObject o = peel(parseAny(r.getObjectId()));
- if (!(o instanceof RevCommit)) {
- continue;
- }
- RevCommit c = (RevCommit) o;
reset(UNINTERESTING | TEMP_MARK);
markStart(c);
boolean commitFound = false;
@@ -577,7 +622,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
}
if (References.isSameObject(next, needle)
|| (next.flags & TEMP_MARK) != 0) {
- result.add(r);
+ result.add(c);
if (returnStrategy == GetMergedIntoStrategy.RETURN_ON_FIRST_FOUND) {
return result;
}
@@ -824,6 +869,8 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
}
/**
+ * Whether only first-parent links should be followed when walking
+ *
* @return whether only first-parent links should be followed when walking.
*
* @since 5.5
@@ -848,7 +895,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
assertNotStarted();
assertNoCommitsMarkedStart();
firstParent = enable;
- queue = new DateRevQueue(firstParent);
+ queue = newDateRevQueue(firstParent);
pending = new StartGenerator(this);
}
@@ -1197,6 +1244,8 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
/**
* Asynchronous object parsing.
*
+ * @param <T>
+ * Type of returned {@code ObjectId}
* @param objectIds
* objects to open from the object store. The supplied collection
* must not be modified until the queue has finished.
@@ -1566,7 +1615,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
}
roots.clear();
- queue = new DateRevQueue(firstParent);
+ queue = newDateRevQueue(firstParent);
pending = new StartGenerator(this);
}
@@ -1587,7 +1636,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
firstParent = false;
objects.clear();
roots.clear();
- queue = new DateRevQueue(firstParent);
+ queue = newDateRevQueue(firstParent);
pending = new StartGenerator(this);
shallowCommitsInitialized = false;
}