Don't pass RevCommits to BatchUpdateOp factories

Using a RevCommit with a RevWalk instance other than the exact one that
created it is a source of difficult-to-find bugs. Some of our
BatchUpdateOp implementations for various reasons took RevCommits in
their assisted constructors, even though the RevWalk that produced the
commit was not guaranteed to be the same RevWalk returned by
Context#getRevWalk(). It happens that all callers were already doing
the right thing, namely calling BatchUpdate#setRepository to set the
RevWalk to the same instance that produced the commits, but there was
no guarantee.

Fix the problem more generally by always passing in ObjectIds to
BatchUpdateOps, and parse the IDs to commits only when using the RevWalk
from the context.

Change-Id: I609bf83342101726755978c5e90f619e09cd3fc4
This commit is contained in:
Dave Borowitz
2017-03-23 15:35:46 -07:00
parent aad79ac07e
commit 6e5adaef69
7 changed files with 56 additions and 48 deletions

View File

@@ -337,7 +337,7 @@ public abstract class BatchUpdate implements AutoCloseable {
return this;
}
public BatchUpdate insertChange(InsertChangeOp op) {
public BatchUpdate insertChange(InsertChangeOp op) throws IOException {
Context ctx = newContext();
Change c = op.createChange(ctx);
checkArgument(

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.update;
import com.google.gerrit.reviewdb.client.Change;
import java.io.IOException;
/**
* Specialization of {@link BatchUpdateOp} for creating changes.
@@ -27,5 +28,5 @@ import com.google.gerrit.reviewdb.client.Change;
* first.
*/
public interface InsertChangeOp extends BatchUpdateOp {
Change createChange(Context ctx);
Change createChange(Context ctx) throws IOException;
}