Ensure RevWalks are always reset before calling markStart

Marking new start commits and iterating a RevWalk is only safe if the
RevWalk was previously reset. Otherwise its internal graph state may
be pointing to some other commit completely unrelated to what the
caller is intending to walk. In the case that the RevWalk previously
had findMergedInto called on it, this manifests as an
UnsupportedOperationException from AlwaysEmptyQueue.

Searched for all instances of "markStart" and ensured they were either
preceded by reset/resetRetain or the RevWalk was brand new.

Change-Id: I1fc34e7b8783921cf0feef1fab9f546700d2fbed
This commit is contained in:
Dave Borowitz
2016-06-14 15:06:50 -04:00
parent 3f528fd78c
commit 676e09881f
3 changed files with 3 additions and 0 deletions

View File

@@ -113,6 +113,7 @@ public class HackPushNegotiateHook implements AdvertiseRefsHook {
// Scan history until the advertisement is full.
RevWalk rw = rp.getRevWalk();
rw.reset();
try {
for (Ref ref : refs) {
try {

View File

@@ -324,6 +324,7 @@ public class SubmoduleOp {
msgbuf.append("\n\n");
try {
subOr.rw.resetRetain(subOr.canMergeFlag);
subOr.rw.markStart(newCommit);
subOr.rw.markUninteresting(subOr.rw.parseCommit(oldId));
for (RevCommit c : subOr.rw) {

View File

@@ -153,6 +153,7 @@ class ChangeNotesParser {
// Don't include initial parse in timer, as this might do more I/O to page
// in the block containing most commits. Later reads are not guaranteed to
// avoid I/O, but often should.
walk.reset();
walk.markStart(walk.parseCommit(tip));
try (Timer1.Context timer = metrics.parseLatency.start(CHANGES)) {