Test conversion of corrupt changes with GERRIT_CHECK_NOTEDB

ConsistencyCheckerIT creates various kinds of corrupt changes that we
think might exist in the wild. In most cases, the right thing to do
when converting these changes is to do our best and store *something*
in NoteDb, even if it can't be successfully read back. At the very
least this allows admins to go in and manually edit the change, using
interactive rebase in the same way they might poke the SQL database
today. This is preferable to throwing the data away during conversion.

The one time we can't do this is when the change belongs to a deleted
project. For now, we actually just discard these changes.

Rework the NoteDbChecker loops so that we attempt to convert all
changes before checking any. This doesn't make ConsistencyCheckerIT
pass, but it does let us verify from the stack trace that all
conversions were successful, even though changes couldn't be read
back.

Change-Id: I87caa451db4e049fa3fc494b79c6c036fba36b1a
This commit is contained in:
Dave Borowitz
2016-03-10 14:19:16 -05:00
parent a9a99130cf
commit 2443905d17
5 changed files with 66 additions and 10 deletions

View File

@@ -58,6 +58,8 @@ import com.google.inject.Inject;
import com.google.inject.util.Providers;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.InvalidObjectIdException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
@@ -520,13 +522,31 @@ public class ChangeRebuilder {
} else {
update.setSubjectForCommit("Create patch set " + ps.getPatchSetId());
}
update.setCommit(rw, ObjectId.fromString(ps.getRevision().get()),
ps.getPushCertificate());
setRevision(update, ps);
update.setGroups(ps.getGroups());
if (ps.isDraft()) {
update.setPatchSetState(PatchSetState.DRAFT);
}
}
private void setRevision(ChangeUpdate update, PatchSet ps)
throws IOException {
String rev = ps.getRevision().get();
String cert = ps.getPushCertificate();
ObjectId id;
try {
id = ObjectId.fromString(rev);
} catch (InvalidObjectIdException e) {
update.setRevisionForMissingCommit(rev, cert);
return;
}
try {
update.setCommit(rw, id, cert);
} catch (MissingObjectException e) {
update.setRevisionForMissingCommit(rev, cert);
return;
}
}
}
private static class PatchLineCommentEvent extends Event {

View File

@@ -115,7 +115,7 @@ public class ChangeUpdate extends AbstractChangeUpdate {
private String submissionId;
private List<PatchLineComment> comments;
private String topic;
private ObjectId commit;
private String commit;
private Set<String> hashtags;
private String changeMessage;
private PatchSetState psState;
@@ -265,7 +265,7 @@ public class ChangeUpdate extends AbstractChangeUpdate {
@VisibleForTesting
ObjectId getCommit() {
return commit;
return ObjectId.fromString(commit);
}
public void setChangeMessage(String changeMessage) {
@@ -325,11 +325,20 @@ public class ChangeUpdate extends AbstractChangeUpdate {
throws IOException {
RevCommit commit = rw.parseCommit(id);
rw.parseBody(commit);
this.commit = commit;
this.commit = commit.name();
subject = commit.getShortMessage();
this.pushCert = pushCert;
}
/**
* Set the revision without depending on the commit being present in the
* repository; should only be used for converting old corrupt commits.
*/
public void setRevisionForMissingCommit(String id, String pushCert) {
commit = id;
this.pushCert = pushCert;
}
public void setHashtags(Set<String> hashtags) {
this.hashtags = hashtags;
}
@@ -366,7 +375,7 @@ public class ChangeUpdate extends AbstractChangeUpdate {
}
if (pushCert != null) {
checkState(commit != null);
cache.get(new RevId(commit.name())).setPushCertificate(pushCert);
cache.get(new RevId(commit)).setPushCertificate(pushCert);
}
Map<RevId, RevisionNoteBuilder> builders = cache.getBuilders();
checkComments(rnm.revisionNotes, builders);
@@ -487,7 +496,7 @@ public class ChangeUpdate extends AbstractChangeUpdate {
}
if (commit != null) {
addFooter(msg, FOOTER_COMMIT, commit.name());
addFooter(msg, FOOTER_COMMIT, commit);
}
Joiner comma = Joiner.on(',');