Refuse to rebuild changes with no patch sets

The implementation of NoteDb requires every commit in the meta graph
to have a patch set ID. The implementation of ChangeRebuildImpl was
unintentionally setting the patch set to the current patch set of the
change, even if there were no actual PatchSet entities in ReviewDb to
back that up. Also unintentionally, parsing this result back would
succeed, and even produce the correct Change fields to make
ChangeBundle's diff happy.

Changes in this state are really corrupt, though, and can't be shown
in the UI, among other things. We should just ignore them when
converting to NoteDb, which is equivalent to obliterating them.

Change-Id: I376d89770fb3b3870e7111e5170882a14419e0a2
This commit is contained in:
Dave Borowitz
2016-08-18 10:54:35 -04:00
parent bc425ff53b
commit 64b166dc9c
3 changed files with 32 additions and 0 deletions

View File

@@ -59,6 +59,7 @@ import com.google.gerrit.server.git.RepoRefCache;
import com.google.gerrit.server.git.UpdateException;
import com.google.gerrit.server.notedb.ChangeBundle;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeRebuilder.NoPatchSetsException;
import com.google.gerrit.server.notedb.NoteDbChangeState;
import com.google.gerrit.server.notedb.NoteDbUpdateManager;
import com.google.gerrit.server.notedb.TestChangeRebuilderWrapper;
@@ -954,6 +955,22 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
assertChangeUpToDate(false, id);
}
@Test
public void rebuildChangeWithNoPatchSets() throws Exception {
PushOneCommit.Result r = createChange();
Change.Id id = r.getPatchSetId().getParentKey();
db.changes().beginTransaction(id);
try {
db.patchSets().delete(db.patchSets().byChange(id));
db.commit();
} finally {
db.rollback();
}
exception.expect(NoPatchSetsException.class);
checker.rebuildAndCheckChanges(id);
}
private void assertChangesReadOnly(RestApiException e) throws Exception {
Throwable cause = e.getCause();
assertThat(cause).isInstanceOf(UpdateException.class);