Merge "RevWalk: new topo sort to not mix lines of history"
This commit is contained in:
commit
24fb3a67b5
|
@ -163,6 +163,23 @@ public void testTopoSort() throws Exception {
|
||||||
assertNull(rw.next());
|
assertNull(rw.next());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTopoNonIntermixSort() throws Exception {
|
||||||
|
RevCommit a = commit();
|
||||||
|
RevCommit b1 = commit(a);
|
||||||
|
RevCommit b2 = commit(a);
|
||||||
|
RevCommit c = commit(b1, b2);
|
||||||
|
|
||||||
|
rw.reset();
|
||||||
|
rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER);
|
||||||
|
rw.setFirstParent(true);
|
||||||
|
markStart(c);
|
||||||
|
assertCommit(c, rw.next());
|
||||||
|
assertCommit(b1, rw.next());
|
||||||
|
assertCommit(a, rw.next());
|
||||||
|
assertNull(rw.next());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCommitTimeSort() throws Exception {
|
public void testCommitTimeSort() throws Exception {
|
||||||
RevCommit a = commit();
|
RevCommit a = commit();
|
||||||
|
@ -428,4 +445,39 @@ public void testWithTopoSortAndTreeFilter2() throws Exception {
|
||||||
assertCommit(c, rw.next());
|
assertCommit(c, rw.next());
|
||||||
assertNull(rw.next());
|
assertNull(rw.next());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithTopoNonIntermixSortAndTreeFilter() throws Exception {
|
||||||
|
RevCommit a = commit();
|
||||||
|
RevCommit b = commit(tree(file("0", blob("b"))), a);
|
||||||
|
RevCommit c = commit(tree(file("0", blob("c"))), b, a);
|
||||||
|
RevCommit d = commit(tree(file("0", blob("d"))), c);
|
||||||
|
|
||||||
|
rw.reset();
|
||||||
|
rw.setFirstParent(true);
|
||||||
|
rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER, true);
|
||||||
|
rw.setTreeFilter(PathFilterGroup.createFromStrings("0"));
|
||||||
|
markStart(d);
|
||||||
|
assertCommit(d, rw.next());
|
||||||
|
assertCommit(c, rw.next());
|
||||||
|
assertCommit(b, rw.next());
|
||||||
|
assertNull(rw.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithTopoNonIntermixSortAndTreeFilter2() throws Exception {
|
||||||
|
RevCommit a = commit();
|
||||||
|
RevCommit b = commit(tree(file("0", blob("b"))), a);
|
||||||
|
RevCommit c = commit(tree(file("0", blob("c"))), a, b);
|
||||||
|
RevCommit d = commit(tree(file("0", blob("d"))), c);
|
||||||
|
|
||||||
|
rw.reset();
|
||||||
|
rw.setFirstParent(true);
|
||||||
|
rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER, true);
|
||||||
|
rw.setTreeFilter(PathFilterGroup.createFromStrings("0"));
|
||||||
|
markStart(d);
|
||||||
|
assertCommit(d, rw.next());
|
||||||
|
assertCommit(c, rw.next());
|
||||||
|
assertNull(rw.next());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,12 @@
|
||||||
|
|
||||||
package org.eclipse.jgit.revwalk;
|
package org.eclipse.jgit.revwalk;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.internal.JGitText;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class RevWalkSortTest extends RevWalkTestCase {
|
public class RevWalkSortTest extends RevWalkTestCase {
|
||||||
|
@ -144,4 +147,171 @@ public void testSort_TOPO_REVERSE() throws Exception {
|
||||||
assertCommit(d, rw.next());
|
assertCommit(d, rw.next());
|
||||||
assertNull(rw.next());
|
assertNull(rw.next());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSort_TOPO_NON_INTERMIX() throws Exception {
|
||||||
|
// c1 is back dated before its parent.
|
||||||
|
//
|
||||||
|
final RevCommit a = commit();
|
||||||
|
final RevCommit b = commit(a);
|
||||||
|
final RevCommit c1 = commit(-5, b);
|
||||||
|
final RevCommit c2 = commit(10, b);
|
||||||
|
final RevCommit d = commit(c1, c2);
|
||||||
|
|
||||||
|
rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER);
|
||||||
|
markStart(d);
|
||||||
|
assertCommit(d, rw.next());
|
||||||
|
assertCommit(c2, rw.next());
|
||||||
|
assertCommit(c1, rw.next());
|
||||||
|
assertCommit(b, rw.next());
|
||||||
|
assertCommit(a, rw.next());
|
||||||
|
assertNull(rw.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSort_TOPO_NON_INTERMIX_OutOfOrderCommitTimes()
|
||||||
|
throws Exception {
|
||||||
|
// b is committed before c2 in a different line of history.
|
||||||
|
//
|
||||||
|
final RevCommit a = commit();
|
||||||
|
final RevCommit c1 = commit(a);
|
||||||
|
final RevCommit b = commit(a);
|
||||||
|
final RevCommit c2 = commit(c1);
|
||||||
|
final RevCommit d = commit(b, c2);
|
||||||
|
|
||||||
|
rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER);
|
||||||
|
markStart(d);
|
||||||
|
assertCommit(d, rw.next());
|
||||||
|
assertCommit(c2, rw.next());
|
||||||
|
assertCommit(c1, rw.next());
|
||||||
|
assertCommit(b, rw.next());
|
||||||
|
assertCommit(a, rw.next());
|
||||||
|
assertNull(rw.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSort_TOPO_NON_INTERMIX_MultipleLinesOfHistory()
|
||||||
|
throws Exception {
|
||||||
|
final RevCommit a1 = commit();
|
||||||
|
final RevCommit b1 = commit(a1);
|
||||||
|
final RevCommit a2 = commit(a1, b1);
|
||||||
|
final RevCommit b2 = commit(b1);
|
||||||
|
final RevCommit b3 = commit(b1);
|
||||||
|
final RevCommit a3 = commit(a2, b2);
|
||||||
|
final RevCommit a4 = commit(a3, b3);
|
||||||
|
|
||||||
|
rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER);
|
||||||
|
markStart(a4);
|
||||||
|
assertCommit(a4, rw.next());
|
||||||
|
assertCommit(b3, rw.next());
|
||||||
|
assertCommit(a3, rw.next());
|
||||||
|
assertCommit(b2, rw.next());
|
||||||
|
assertCommit(a2, rw.next());
|
||||||
|
assertCommit(b1, rw.next());
|
||||||
|
assertCommit(a1, rw.next());
|
||||||
|
assertNull(rw.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSort_TOPO_NON_INTERMIX_REVERSE() throws Exception {
|
||||||
|
// c1 is back dated before its parent.
|
||||||
|
//
|
||||||
|
final RevCommit a = commit();
|
||||||
|
final RevCommit b = commit(a);
|
||||||
|
final RevCommit c1 = commit(-5, b);
|
||||||
|
final RevCommit c2 = commit(10, b);
|
||||||
|
final RevCommit d = commit(c1, c2);
|
||||||
|
|
||||||
|
rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER);
|
||||||
|
rw.sort(RevSort.REVERSE, true);
|
||||||
|
markStart(d);
|
||||||
|
assertCommit(a, rw.next());
|
||||||
|
assertCommit(b, rw.next());
|
||||||
|
assertCommit(c1, rw.next());
|
||||||
|
assertCommit(c2, rw.next());
|
||||||
|
assertCommit(d, rw.next());
|
||||||
|
assertNull(rw.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSort_TOPO_NON_INTERMIX_REVERSE_MultipleLinesOfHistory()
|
||||||
|
throws Exception {
|
||||||
|
final RevCommit a1 = commit();
|
||||||
|
final RevCommit b1 = commit(a1);
|
||||||
|
final RevCommit a2 = commit(a1, b1);
|
||||||
|
final RevCommit b2 = commit(b1);
|
||||||
|
final RevCommit b3 = commit(b1);
|
||||||
|
final RevCommit a3 = commit(a2, b2);
|
||||||
|
final RevCommit a4 = commit(a3, b3);
|
||||||
|
|
||||||
|
rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER);
|
||||||
|
rw.sort(RevSort.REVERSE, true);
|
||||||
|
markStart(a4);
|
||||||
|
assertCommit(a1, rw.next());
|
||||||
|
assertCommit(b1, rw.next());
|
||||||
|
assertCommit(a2, rw.next());
|
||||||
|
assertCommit(b2, rw.next());
|
||||||
|
assertCommit(a3, rw.next());
|
||||||
|
assertCommit(b3, rw.next());
|
||||||
|
assertCommit(a4, rw.next());
|
||||||
|
assertNull(rw.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSort_TOPO_NON_INTERMIX_ParentOfMultipleStartChildren()
|
||||||
|
throws Exception {
|
||||||
|
final RevCommit a = commit();
|
||||||
|
final RevCommit b = commit(a);
|
||||||
|
final RevCommit c = commit(a);
|
||||||
|
final RevCommit d1 = commit(a);
|
||||||
|
final RevCommit d2 = commit(d1);
|
||||||
|
final RevCommit e = commit(a);
|
||||||
|
|
||||||
|
rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER);
|
||||||
|
markStart(b);
|
||||||
|
markStart(c);
|
||||||
|
markStart(d2);
|
||||||
|
markStart(e);
|
||||||
|
assertCommit(e, rw.next());
|
||||||
|
assertCommit(d2, rw.next());
|
||||||
|
assertCommit(d1, rw.next());
|
||||||
|
assertCommit(c, rw.next());
|
||||||
|
assertCommit(b, rw.next());
|
||||||
|
assertCommit(a, rw.next());
|
||||||
|
assertNull(rw.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSort_TOPO_NON_INTERMIX_Uninteresting() throws Exception {
|
||||||
|
final RevCommit a1 = commit();
|
||||||
|
final RevCommit a2 = commit(a1);
|
||||||
|
final RevCommit a3 = commit(a2);
|
||||||
|
final RevCommit b = commit(a1);
|
||||||
|
final RevCommit a4 = commit(a3, b);
|
||||||
|
|
||||||
|
rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER);
|
||||||
|
markStart(a4);
|
||||||
|
markUninteresting(a2);
|
||||||
|
assertCommit(a4, rw.next());
|
||||||
|
assertCommit(b, rw.next());
|
||||||
|
assertCommit(a3, rw.next());
|
||||||
|
assertNull(rw.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSort_TOPO_NON_INTERMIX_and_TOPO_throws() throws Exception {
|
||||||
|
final RevCommit a = commit();
|
||||||
|
|
||||||
|
rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER);
|
||||||
|
rw.sort(RevSort.TOPO, true);
|
||||||
|
markStart(a);
|
||||||
|
try {
|
||||||
|
rw.next();
|
||||||
|
fail("did not throw IllegalStateException");
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
assertEquals(
|
||||||
|
JGitText.get().cannotCombineTopoSortWithTopoNonIntermixSort,
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ cannotChangeActionOnComment=Cannot change action on comment line in git-rebase-t
|
||||||
cannotCheckoutFromUnbornBranch=Cannot check out from unborn branch
|
cannotCheckoutFromUnbornBranch=Cannot check out from unborn branch
|
||||||
cannotCheckoutOursSwitchBranch=Checking out ours/theirs is only possible when checking out index, not when switching branches.
|
cannotCheckoutOursSwitchBranch=Checking out ours/theirs is only possible when checking out index, not when switching branches.
|
||||||
cannotCombineSquashWithNoff=Cannot combine --squash with --no-ff.
|
cannotCombineSquashWithNoff=Cannot combine --squash with --no-ff.
|
||||||
|
cannotCombineTopoSortWithTopoNonIntermixSort=Cannot combine sorts TOPO and TOPO_NON_INTERMIX.
|
||||||
cannotCombineTreeFilterWithRevFilter=Cannot combine TreeFilter {0} with RevFilter {1}.
|
cannotCombineTreeFilterWithRevFilter=Cannot combine TreeFilter {0} with RevFilter {1}.
|
||||||
cannotCommitOnARepoWithState=Cannot commit on a repo with state: {0}
|
cannotCommitOnARepoWithState=Cannot commit on a repo with state: {0}
|
||||||
cannotCommitWriteTo=Cannot commit write to {0}
|
cannotCommitWriteTo=Cannot commit write to {0}
|
||||||
|
|
|
@ -82,6 +82,7 @@ public static JGitText get() {
|
||||||
/***/ public String cannotCheckoutFromUnbornBranch;
|
/***/ public String cannotCheckoutFromUnbornBranch;
|
||||||
/***/ public String cannotCheckoutOursSwitchBranch;
|
/***/ public String cannotCheckoutOursSwitchBranch;
|
||||||
/***/ public String cannotCombineSquashWithNoff;
|
/***/ public String cannotCombineSquashWithNoff;
|
||||||
|
/***/ public String cannotCombineTopoSortWithTopoNonIntermixSort;
|
||||||
/***/ public String cannotCombineTreeFilterWithRevFilter;
|
/***/ public String cannotCombineTreeFilterWithRevFilter;
|
||||||
/***/ public String cannotCommitOnARepoWithState;
|
/***/ public String cannotCommitOnARepoWithState;
|
||||||
/***/ public String cannotCommitWriteTo;
|
/***/ public String cannotCommitWriteTo;
|
||||||
|
|
|
@ -152,6 +152,7 @@ public String toString() {
|
||||||
*/
|
*/
|
||||||
protected void appendCoreFlags(StringBuilder s) {
|
protected void appendCoreFlags(StringBuilder s) {
|
||||||
s.append((flags & RevWalk.TOPO_DELAY) != 0 ? 'o' : '-');
|
s.append((flags & RevWalk.TOPO_DELAY) != 0 ? 'o' : '-');
|
||||||
|
s.append((flags & RevWalk.TOPO_QUEUED) != 0 ? 'q' : '-');
|
||||||
s.append((flags & RevWalk.TEMP_MARK) != 0 ? 't' : '-');
|
s.append((flags & RevWalk.TEMP_MARK) != 0 ? 't' : '-');
|
||||||
s.append((flags & RevWalk.REWRITE) != 0 ? 'r' : '-');
|
s.append((flags & RevWalk.REWRITE) != 0 ? 'r' : '-');
|
||||||
s.append((flags & RevWalk.UNINTERESTING) != 0 ? 'u' : '-');
|
s.append((flags & RevWalk.UNINTERESTING) != 0 ? 'u' : '-');
|
||||||
|
|
|
@ -39,6 +39,18 @@ public enum RevSort {
|
||||||
*/
|
*/
|
||||||
TOPO,
|
TOPO,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Topological sorting (all children before parents) without intermixing
|
||||||
|
* lines of history.
|
||||||
|
* <p>
|
||||||
|
* This behavior more closely resembles C Git's git-log --topo-order than
|
||||||
|
* {@link #TOPO}. See C Git's topo-order <a href=
|
||||||
|
* "https://git-scm.com/docs/git-log#Documentation/git-log.txt---topo-order">description</a>.
|
||||||
|
*
|
||||||
|
* @since 5.8
|
||||||
|
*/
|
||||||
|
TOPO_KEEP_BRANCH_TOGETHER,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flip the output into the reverse ordering.
|
* Flip the output into the reverse ordering.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
@ -131,8 +131,17 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
|
||||||
*/
|
*/
|
||||||
static final int TOPO_DELAY = 1 << 5;
|
static final int TOPO_DELAY = 1 << 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporary mark for use within {@link TopoNonIntermixSortGenerator}.
|
||||||
|
* <p>
|
||||||
|
* This mark indicates the commit has been queued for emission in
|
||||||
|
* {@link TopoSortGenerator} and can be produced. This mark is removed when
|
||||||
|
* the commit has been produced.
|
||||||
|
*/
|
||||||
|
static final int TOPO_QUEUED = 1 << 6;
|
||||||
|
|
||||||
/** Number of flag bits we keep internal for our own use. See above flags. */
|
/** Number of flag bits we keep internal for our own use. See above flags. */
|
||||||
static final int RESERVED_FLAGS = 6;
|
static final int RESERVED_FLAGS = 7;
|
||||||
|
|
||||||
private static final int APP_FLAGS = -1 & ~((1 << RESERVED_FLAGS) - 1);
|
private static final int APP_FLAGS = -1 & ~((1 << RESERVED_FLAGS) - 1);
|
||||||
|
|
||||||
|
|
|
@ -135,8 +135,18 @@ RevCommit next() throws MissingObjectException,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (walker.hasRevSort(RevSort.TOPO)
|
if (walker.hasRevSort(RevSort.TOPO)
|
||||||
&& (g.outputType() & SORT_TOPO) == 0)
|
&& walker.hasRevSort(RevSort.TOPO_KEEP_BRANCH_TOGETHER)) {
|
||||||
|
throw new IllegalStateException(JGitText
|
||||||
|
.get().cannotCombineTopoSortWithTopoNonIntermixSort);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walker.hasRevSort(RevSort.TOPO)
|
||||||
|
&& (g.outputType() & SORT_TOPO) == 0) {
|
||||||
g = new TopoSortGenerator(g);
|
g = new TopoSortGenerator(g);
|
||||||
|
} else if (walker.hasRevSort(RevSort.TOPO_KEEP_BRANCH_TOGETHER)
|
||||||
|
&& (g.outputType() & SORT_TOPO) == 0) {
|
||||||
|
g = new TopoNonIntermixSortGenerator(g);
|
||||||
|
}
|
||||||
if (walker.hasRevSort(RevSort.REVERSE))
|
if (walker.hasRevSort(RevSort.REVERSE))
|
||||||
g = new LIFORevQueue(g);
|
g = new LIFORevQueue(g);
|
||||||
if (boundary)
|
if (boundary)
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020, Google LLC. and others
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Distribution License v. 1.0 which is available at
|
||||||
|
* https://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.eclipse.jgit.revwalk;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||||
|
import org.eclipse.jgit.errors.MissingObjectException;
|
||||||
|
|
||||||
|
/** Sorts commits in topological order without intermixing lines of history. */
|
||||||
|
class TopoNonIntermixSortGenerator extends Generator {
|
||||||
|
private static final int TOPO_QUEUED = RevWalk.TOPO_QUEUED;
|
||||||
|
|
||||||
|
private final FIFORevQueue pending;
|
||||||
|
|
||||||
|
private final int outputType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new sorter and completely spin the generator.
|
||||||
|
* <p>
|
||||||
|
* When the constructor completes the supplied generator will have no
|
||||||
|
* commits remaining, as all of the commits will be held inside of this
|
||||||
|
* generator's internal buffer.
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
* generator to pull all commits out of, and into this buffer.
|
||||||
|
* @throws MissingObjectException
|
||||||
|
* @throws IncorrectObjectTypeException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
TopoNonIntermixSortGenerator(Generator s) throws MissingObjectException,
|
||||||
|
IncorrectObjectTypeException, IOException {
|
||||||
|
super(s.firstParent);
|
||||||
|
pending = new FIFORevQueue(firstParent);
|
||||||
|
outputType = s.outputType() | SORT_TOPO;
|
||||||
|
s.shareFreeList(pending);
|
||||||
|
for (;;) {
|
||||||
|
final RevCommit c = s.next();
|
||||||
|
if (c == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((c.flags & TOPO_QUEUED) == 0) {
|
||||||
|
for (RevCommit p : c.parents) {
|
||||||
|
p.inDegree++;
|
||||||
|
|
||||||
|
if (firstParent) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.flags |= TOPO_QUEUED;
|
||||||
|
pending.add(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
int outputType() {
|
||||||
|
return outputType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void shareFreeList(BlockRevQueue q) {
|
||||||
|
q.shareFreeList(pending);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
RevCommit next() throws MissingObjectException,
|
||||||
|
IncorrectObjectTypeException, IOException {
|
||||||
|
for (;;) {
|
||||||
|
final RevCommit c = pending.next();
|
||||||
|
if (c == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.inDegree > 0) {
|
||||||
|
// At least one of our children is missing. We delay
|
||||||
|
// production until all of our children are output.
|
||||||
|
//
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((c.flags & TOPO_QUEUED) == 0) {
|
||||||
|
// c is a parent that already produced or a parent that
|
||||||
|
// was never in the priority queue and should never produce.
|
||||||
|
//
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RevCommit p : c.parents) {
|
||||||
|
if (--p.inDegree == 0 && (p.flags & TOPO_QUEUED) != 0) {
|
||||||
|
// The parent has no unproduced interesting children. unpop
|
||||||
|
// the parent so it goes right behind this child. This means
|
||||||
|
// that this parent commit may appear in "pending" more than
|
||||||
|
// once, but this is safe since upon the second and
|
||||||
|
// subsequent iterations with this commit, it will no longer
|
||||||
|
// have TOPO_QUEUED set, and thus will be skipped.
|
||||||
|
//
|
||||||
|
pending.unpop(p);
|
||||||
|
}
|
||||||
|
if (firstParent) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.flags &= ~TOPO_QUEUED;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue