Merge "Revert "Fix GWT UI AddFileBox to provide path suggestions continuously""
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index 6ae9995..434dc95 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -20,3 +20,5 @@
# Format all Java files with google-java-format
292fa154c18b5a203c1aa211dce4efd54e6e8e0a
+111168482164db0cbe6a31630908ab607abc9989
+42ace3c4f41363b41486fe6cf8a3519f296ba4f4
diff --git a/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/ConfigAnnotationParser.java b/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/ConfigAnnotationParser.java
index 5d6a854..48a166c 100644
--- a/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/ConfigAnnotationParser.java
+++ b/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/ConfigAnnotationParser.java
@@ -59,7 +59,7 @@
}
} else {
throw new IllegalArgumentException(
- "GerritConfig.name must be of the format" + " section.subsection.name or section.name");
+ "GerritConfig.name must be of the format section.subsection.name or section.name");
}
}
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
index df82e21..13baea9f 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -1214,7 +1214,7 @@
assertThat(msg.rcpt()).containsExactly(user.emailAddress);
assertThat(msg.body()).contains(admin.fullName + " has removed a vote on this change.\n");
assertThat(msg.body())
- .contains("Removed Code-Review+1 by " + user.fullName + " <" + user.email + ">" + "\n");
+ .contains("Removed Code-Review+1 by " + user.fullName + " <" + user.email + ">\n");
Map<String, Short> m =
gApi.changes().id(r.getChangeId()).reviewer(user.getId().toString()).votes();
@@ -2140,7 +2140,7 @@
testRepo,
"Ignore Verified",
"rules.pl",
- "submit_rule(submit(CR)) :-\n" + " gerrit:max_with_block(-2, 2, 'Code-Review', CR).");
+ "submit_rule(submit(CR)) :-\n gerrit:max_with_block(-2, 2, 'Code-Review', CR).");
push2.to(RefNames.REFS_CONFIG);
change = gApi.changes().id(r.getChangeId()).get();
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
index 50cef79..cde75bc 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
@@ -367,7 +367,7 @@
PushOneCommit.Result r1 = createChange();
// Push another new change (change 2)
- String subject = "Test change\n\n" + "Change-Id: Ideadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
+ String subject = "Test change\n\nChange-Id: Ideadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
PushOneCommit push =
pushFactory.create(
db, admin.getIdent(), testRepo, subject, "another_file.txt", "another content");
@@ -559,7 +559,7 @@
exception.expect(BadRequestException.class);
exception.expectMessage(
- "Cherry Pick: Parent 0 does not exist. Please" + " specify a parent in range [1, 2].");
+ "Cherry Pick: Parent 0 does not exist. Please specify a parent in range [1, 2].");
gApi.changes().id(mergeChangeResult.getChangeId()).current().cherryPick(cherryPickInput);
}
@@ -580,7 +580,7 @@
exception.expect(BadRequestException.class);
exception.expectMessage(
- "Cherry Pick: Parent 3 does not exist. Please" + " specify a parent in range [1, 2].");
+ "Cherry Pick: Parent 3 does not exist. Please specify a parent in range [1, 2].");
gApi.changes().id(mergeChangeResult.getChangeId()).current().cherryPick(cherryPickInput);
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java
index faa21cf..5241f52 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java
@@ -197,7 +197,7 @@
exception.expect(BadRequestException.class);
exception.expectMessage(
String.format(
- "A description is required for the " + "suggested fix of the robot comment on %s",
+ "A description is required for the suggested fix of the robot comment on %s",
withFixRobotCommentInput.path));
addRobotComment(changeId, withFixRobotCommentInput);
}
@@ -256,7 +256,7 @@
exception.expect(BadRequestException.class);
exception.expectMessage(
String.format(
- "A file path must be given for the " + "replacement of the robot comment on %s",
+ "A file path must be given for the replacement of the robot comment on %s",
withFixRobotCommentInput.path));
addRobotComment(changeId, withFixRobotCommentInput);
}
@@ -301,7 +301,7 @@
exception.expect(BadRequestException.class);
exception.expectMessage(
String.format(
- "A range must be given for the " + "replacement of the robot comment on %s",
+ "A range must be given for the replacement of the robot comment on %s",
withFixRobotCommentInput.path));
addRobotComment(changeId, withFixRobotCommentInput);
}
@@ -315,7 +315,7 @@
exception.expect(BadRequestException.class);
exception.expectMessage(
String.format(
- "Range (13:9 - 5:10) is not " + "valid for the replacement of the robot comment on %s",
+ "Range (13:9 - 5:10) is not valid for the replacement of the robot comment on %s",
withFixRobotCommentInput.path));
addRobotComment(changeId, withFixRobotCommentInput);
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
index 72a391c..03c182dd 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
@@ -161,7 +161,7 @@
r1.assertOkStatus();
r1.assertChange(Change.Status.NEW, null);
r1.assertMessage(
- "New changes:\n" + " " + url + id1 + " " + r1.getCommit().getShortMessage() + "\n");
+ "New changes:\n " + url + id1 + " " + r1.getCommit().getShortMessage() + "\n");
testRepo.reset(initialHead);
String newMsg = r1.getCommit().getShortMessage() + " v2";
@@ -238,7 +238,7 @@
gApi.accounts().self().setWatchedProjects(projectsToWatch);
TestAccount user2 = accounts.user2();
- String pushSpec = "refs/for/master" + "%reviewer=" + user.email + ",cc=" + user2.email;
+ String pushSpec = "refs/for/master%reviewer=" + user.email + ",cc=" + user2.email;
sender.clear();
PushOneCommit.Result r = pushTo(pushSpec + ",notify=" + NotifyHandling.NONE);
@@ -991,7 +991,7 @@
}
private void testpushWithInvalidChangeId() throws Exception {
- createCommit(testRepo, "Message with invalid Change-Id\n" + "\n" + "Change-Id: X\n");
+ createCommit(testRepo, "Message with invalid Change-Id\n\nChange-Id: X\n");
pushForReviewRejected(testRepo, "invalid Change-Id line format in commit message footer");
ProjectConfig config = projectCache.checkedGet(project).getConfig();
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
index 068eb4f..0c81a35 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
@@ -320,7 +320,7 @@
.getAdvertisedRef("refs/heads/master")
.getObjectId();
- assertWithMessage("submodule subscription update " + "should have made one commit")
+ assertWithMessage("submodule subscription update should have made one commit")
.that(superRepo.getRepository().resolve("origin/master^"))
.isEqualTo(superPreviousId);
}
@@ -403,7 +403,7 @@
.getAdvertisedRef("refs/heads/master")
.getObjectId();
- assertWithMessage("submodule subscription update " + "should have made one commit")
+ assertWithMessage("submodule subscription update should have made one commit")
.that(superRepo.getRepository().resolve("origin/master^"))
.isEqualTo(superPreviousId);
}
@@ -450,7 +450,7 @@
.getAdvertisedRef("refs/heads/master")
.getObjectId();
- assertWithMessage("submodule subscription update " + "should have made one commit")
+ assertWithMessage("submodule subscription update should have made one commit")
.that(superRepo.getRepository().resolve("origin/master^"))
.isEqualTo(superPreviousId);
}
@@ -492,7 +492,7 @@
.getAdvertisedRef("refs/heads/master")
.getObjectId();
- assertWithMessage("submodule subscription update " + "should have made one commit")
+ assertWithMessage("submodule subscription update should have made one commit")
.that(superRepo.getRepository().resolve("origin/master^"))
.isEqualTo(superPreviousId);
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ActionsIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ActionsIT.java
index 12b3435..87436e7 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ActionsIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ActionsIT.java
@@ -105,8 +105,7 @@
assertThat(info.enabled).isNull();
assertThat(info.label).isEqualTo("Submit whole topic");
assertThat(info.method).isEqualTo("POST");
- assertThat(info.title)
- .isEqualTo("This change depends on other " + "changes which are not ready");
+ assertThat(info.title).isEqualTo("This change depends on other changes which are not ready");
} else {
noSubmitWholeTopicAssertions(actions, 1);
@@ -307,7 +306,7 @@
assertThat(info.title)
.isEqualTo(
String.format(
- "Submit patch set 1 and ancestors (%d changes " + "altogether) into master",
+ "Submit patch set 1 and ancestors (%d changes altogether) into master",
nrChanges));
}
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java
index 5dc8a0c..66966c3 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java
@@ -85,8 +85,7 @@
assertThat(result.input).isEqualTo(mediumGroup);
assertThat(result.confirm).isTrue();
assertThat(result.error)
- .contains(
- "has " + mediumGroupSize + " members. Do you want to add them" + " all as reviewers?");
+ .contains("has " + mediumGroupSize + " members. Do you want to add them all as reviewers?");
assertThat(result.reviewers).isNull();
// Add medium group with confirmation.
@@ -514,8 +513,7 @@
assertThat(reviewerResult).isNotNull();
assertThat(reviewerResult.confirm).isTrue();
assertThat(reviewerResult.error)
- .contains(
- "has " + mediumGroupSize + " members. Do you want to add them all" + " as reviewers?");
+ .contains("has " + mediumGroupSize + " members. Do you want to add them all as reviewers?");
// No labels should have changed, and no reviewers/CCs should have been added.
c = gApi.changes().id(r.getChangeId()).get();
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ConfigChangeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ConfigChangeIT.java
index cef5e6e..c1784c2 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ConfigChangeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ConfigChangeIT.java
@@ -155,7 +155,7 @@
.asString();
// Append and push malformed project config
- String pattern = "[access]\n" + "\tinheritFrom = " + allProjects.get() + "\n";
+ String pattern = "[access]\n\tinheritFrom = " + allProjects.get() + "\n";
String doubleInherit = pattern + "\tinheritFrom = " + parent.get() + "\n";
config = config.replace(pattern, doubleInherit);
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/DeleteVoteIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/DeleteVoteIT.java
index d524f2a..ff4eb3d 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/DeleteVoteIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/DeleteVoteIT.java
@@ -72,7 +72,7 @@
assertThat(msg.rcpt()).containsExactly(user.emailAddress);
assertThat(msg.body()).contains(admin.fullName + " has removed a vote on this change.\n");
assertThat(msg.body())
- .contains("Removed Code-Review+1 by " + user.fullName + " <" + user.email + ">" + "\n");
+ .contains("Removed Code-Review+1 by " + user.fullName + " <" + user.email + ">\n");
endPoint =
"/changes/"
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
index 295aefd..75e7356 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
@@ -393,7 +393,7 @@
createChange(
repo3,
"master",
- "some accompanying changes for change3a in another repo " + "tied together via topic",
+ "some accompanying changes for change3a in another repo tied together via topic",
"a.txt",
"1",
"a-topic-here");
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/PushTagIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/PushTagIT.java
index 4bd8df4..7ed15f4 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/PushTagIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/PushTagIT.java
@@ -204,7 +204,7 @@
commit(user.getIdent(), "subject");
boolean createTag = tagName == null;
- tagName = MoreObjects.firstNonNull(tagName, "v1" + "_" + System.nanoTime());
+ tagName = MoreObjects.firstNonNull(tagName, "v1_" + System.nanoTime());
switch (tagType) {
case LIGHTWEIGHT:
break;
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/ConsistencyCheckerIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/ConsistencyCheckerIT.java
index b76a96a..a427dd3 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/ConsistencyCheckerIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/ConsistencyCheckerIT.java
@@ -154,7 +154,7 @@
assertProblems(
ctl,
null,
- problem("Invalid revision on patch set 1:" + " fooooooooooooooooooooooooooooooooooooooo"));
+ problem("Invalid revision on patch set 1: fooooooooooooooooooooooooooooooooooooooo"));
}
// No test for ref existing but object missing; InMemoryRepository won't let
@@ -170,7 +170,7 @@
ctl,
null,
problem("Ref missing: " + ps.getId().toRefName()),
- problem("Object missing: patch set 2:" + " deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
+ problem("Object missing: patch set 2: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
}
@Test
@@ -725,7 +725,7 @@
testRepo
.commit()
.parent(parent)
- .message(commit.getShortMessage() + "\n" + "\n" + "Change-Id: " + badId + "\n")
+ .message(commit.getShortMessage() + "\n\nChange-Id: " + badId + "\n")
.create();
testRepo.getRevWalk().parseBody(mergedAs);
assertThat(mergedAs.getFooterLines(FooterConstants.CHANGE_ID)).containsExactly(badId);
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/notedb/NoteDbPrimaryIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/notedb/NoteDbPrimaryIT.java
index ef5e7cf..da6aef6 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/notedb/NoteDbPrimaryIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/notedb/NoteDbPrimaryIT.java
@@ -17,6 +17,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assert_;
import static com.google.common.truth.TruthJUnit.assume;
+import static com.google.gerrit.server.notedb.ChangeNoteUtil.formatTime;
import static com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage.REVIEW_DB;
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -27,6 +28,8 @@
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
@@ -34,6 +37,7 @@
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.api.changes.DraftInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
+import com.google.gerrit.extensions.api.changes.ReviewInput.CommentInput;
import com.google.gerrit.extensions.client.ChangeStatus;
import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
@@ -41,14 +45,24 @@
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.ChangeMessage;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDbUtil;
+import com.google.gerrit.server.ChangeMessagesUtil;
+import com.google.gerrit.server.CommentsUtil;
+import com.google.gerrit.server.InternalUser;
import com.google.gerrit.server.config.AllUsersName;
+import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.RepoRefCache;
+import com.google.gerrit.server.notedb.ChangeBundle;
+import com.google.gerrit.server.notedb.ChangeBundleReader;
import com.google.gerrit.server.notedb.ChangeNotes;
+import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.notedb.NoteDbChangeState;
import com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage;
import com.google.gerrit.server.notedb.PrimaryStorageMigrator;
import com.google.gerrit.server.notedb.TestChangeRebuilderWrapper;
+import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.testutil.ConfigSuite;
import com.google.gerrit.testutil.NoteDbMode;
import com.google.gerrit.testutil.TestTimeUtil;
@@ -62,7 +76,10 @@
import java.util.List;
import java.util.Optional;
import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -78,8 +95,13 @@
}
@Inject private AllUsersName allUsers;
-
+ @Inject private BatchUpdate.Factory batchUpdateFactory;
+ @Inject private ChangeBundleReader bundleReader;
+ @Inject private CommentsUtil commentsUtil;
@Inject private TestChangeRebuilderWrapper rebuilderWrapper;
+ @Inject private ChangeControl.GenericFactory changeControlFactory;
+ @Inject private ChangeUpdate.Factory updateFactory;
+ @Inject private InternalUser.Factory internalUserFactory;
private PrimaryStorageMigrator migrator;
@@ -94,7 +116,17 @@
private PrimaryStorageMigrator newMigrator(
@Nullable Retryer<NoteDbChangeState> ensureRebuiltRetryer) {
return new PrimaryStorageMigrator(
- cfg, Providers.of(db), repoManager, allUsers, rebuilderWrapper, ensureRebuiltRetryer);
+ cfg,
+ Providers.of(db),
+ repoManager,
+ allUsers,
+ rebuilderWrapper,
+ ensureRebuiltRetryer,
+ changeControlFactory,
+ queryProvider,
+ updateFactory,
+ internalUserFactory,
+ batchUpdateFactory);
}
@After
@@ -368,6 +400,105 @@
assertNoteDbPrimary(id);
}
+ @Test
+ public void rebuildReviewDb() throws Exception {
+ Change c = createChange().getChange().change();
+ Change.Id id = c.getId();
+
+ CommentInput cin = new CommentInput();
+ cin.line = 1;
+ cin.message = "Published comment";
+ ReviewInput rin = ReviewInput.approve();
+ rin.comments = ImmutableMap.of(PushOneCommit.FILE_NAME, ImmutableList.of(cin));
+ gApi.changes().id(id.get()).current().review(ReviewInput.approve());
+
+ DraftInput din = new DraftInput();
+ din.path = PushOneCommit.FILE_NAME;
+ din.line = 1;
+ din.message = "Draft comment";
+ gApi.changes().id(id.get()).current().createDraft(din);
+ gApi.changes().id(id.get()).current().review(ReviewInput.approve());
+ gApi.changes().id(id.get()).current().createDraft(din);
+
+ assertThat(db.changeMessages().byChange(id)).isNotEmpty();
+ assertThat(db.patchSets().byChange(id)).isNotEmpty();
+ assertThat(db.patchSetApprovals().byChange(id)).isNotEmpty();
+ assertThat(db.patchComments().byChange(id)).isNotEmpty();
+
+ ChangeBundle noteDbBundle =
+ ChangeBundle.fromNotes(commentsUtil, notesFactory.create(db, project, id));
+
+ setNoteDbPrimary(id);
+
+ db.changeMessages().delete(db.changeMessages().byChange(id));
+ db.patchSets().delete(db.patchSets().byChange(id));
+ db.patchSetApprovals().delete(db.patchSetApprovals().byChange(id));
+ db.patchComments().delete(db.patchComments().byChange(id));
+ ChangeMessage bogusMessage =
+ ChangeMessagesUtil.newMessage(
+ c.currentPatchSetId(),
+ identifiedUserFactory.create(admin.getId()),
+ TimeUtil.nowTs(),
+ "some message",
+ null);
+ db.changeMessages().insert(Collections.singleton(bogusMessage));
+
+ rebuilderWrapper.rebuildReviewDb(db, project, id);
+
+ assertThat(db.changeMessages().byChange(id)).isNotEmpty();
+ assertThat(db.patchSets().byChange(id)).isNotEmpty();
+ assertThat(db.patchSetApprovals().byChange(id)).isNotEmpty();
+ assertThat(db.patchComments().byChange(id)).isNotEmpty();
+
+ ChangeBundle reviewDbBundle = bundleReader.fromReviewDb(ReviewDbUtil.unwrapDb(db), id);
+ assertThat(reviewDbBundle.differencesFrom(noteDbBundle)).isEmpty();
+ }
+
+ @Test
+ public void rebuildReviewDbRequiresNoteDbPrimary() throws Exception {
+ Change.Id id = createChange().getChange().getId();
+
+ exception.expect(OrmException.class);
+ exception.expectMessage("primary storage of " + id + " is REVIEW_DB");
+ rebuilderWrapper.rebuildReviewDb(db, project, id);
+ }
+
+ @Test
+ public void migrateBackToReviewDbPrimary() throws Exception {
+ Change c = createChange().getChange().change();
+ Change.Id id = c.getId();
+
+ migrator.migrateToNoteDbPrimary(id);
+ assertNoteDbPrimary(id);
+
+ gApi.changes().id(id.get()).topic("new-topic");
+ assertThat(gApi.changes().id(id.get()).topic()).isEqualTo("new-topic");
+ assertThat(db.changes().get(id).getTopic()).isNotEqualTo("new-topic");
+
+ migrator.migrateToReviewDbPrimary(id, null);
+ ObjectId metaId;
+ try (Repository repo = repoManager.openRepository(c.getProject());
+ RevWalk rw = new RevWalk(repo)) {
+ metaId = repo.exactRef(RefNames.changeMetaRef(id)).getObjectId();
+ RevCommit commit = rw.parseCommit(metaId);
+ rw.parseBody(commit);
+ assertThat(commit.getFullMessage())
+ .contains("Read-only-until: " + formatTime(serverIdent.get(), new Timestamp(0)));
+ }
+ NoteDbChangeState state = NoteDbChangeState.parse(db.changes().get(id));
+ assertThat(state.getPrimaryStorage()).isEqualTo(PrimaryStorage.REVIEW_DB);
+ assertThat(state.getChangeMetaId()).isEqualTo(metaId);
+ assertThat(gApi.changes().id(id.get()).topic()).isEqualTo("new-topic");
+ assertThat(db.changes().get(id).getTopic()).isEqualTo("new-topic");
+
+ ChangeNotes notes = notesFactory.create(db, project, id);
+ assertThat(notes.getRevision()).isEqualTo(metaId); // No rebuilding, change was up to date.
+ assertThat(notes.getReadOnlyUntil()).isNotNull();
+
+ gApi.changes().id(id.get()).topic("reviewdb-topic");
+ assertThat(db.changes().get(id).getTopic()).isEqualTo("reviewdb-topic");
+ }
+
private void setNoteDbPrimary(Change.Id id) throws Exception {
Change c = db.changes().get(id);
assertThat(c).named("change " + id).isNotNull();
diff --git a/gerrit-cache-h2/src/main/java/com/google/gerrit/server/cache/h2/H2CacheImpl.java b/gerrit-cache-h2/src/main/java/com/google/gerrit/server/cache/h2/H2CacheImpl.java
index e489257..b0c7764 100644
--- a/gerrit-cache-h2/src/main/java/com/google/gerrit/server/cache/h2/H2CacheImpl.java
+++ b/gerrit-cache-h2/src/main/java/com/google/gerrit/server/cache/h2/H2CacheImpl.java
@@ -572,7 +572,7 @@
try (Statement s = c.conn.createStatement()) {
long used = 0;
try (ResultSet r =
- s.executeQuery("SELECT" + " SUM(OCTET_LENGTH(k) + OCTET_LENGTH(v))" + " FROM data")) {
+ s.executeQuery("SELECT SUM(OCTET_LENGTH(k) + OCTET_LENGTH(v)) FROM data")) {
used = r.next() ? r.getLong(1) : 0;
}
if (used <= maxSize) {
diff --git a/gerrit-cache-h2/src/test/java/com/google/gerrit/server/cache/h2/H2CacheTest.java b/gerrit-cache-h2/src/test/java/com/google/gerrit/server/cache/h2/H2CacheTest.java
index 87d5db3..15e0de0 100644
--- a/gerrit-cache-h2/src/test/java/com/google/gerrit/server/cache/h2/H2CacheTest.java
+++ b/gerrit-cache-h2/src/test/java/com/google/gerrit/server/cache/h2/H2CacheTest.java
@@ -42,7 +42,7 @@
TypeLiteral<String> keyType = new TypeLiteral<String>() {};
SqlStore<String, Boolean> store =
- new SqlStore<>("jdbc:h2:mem:" + "Test_" + (++dbCnt), keyType, 1 << 20, 0);
+ new SqlStore<>("jdbc:h2:mem:Test_" + (++dbCnt), keyType, 1 << 20, 0);
impl = new H2CacheImpl<>(MoreExecutors.directExecutor(), store, keyType, mem);
}
diff --git a/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GerritPublicKeyChecker.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GerritPublicKeyChecker.java
index fe987f4..b74139a 100644
--- a/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GerritPublicKeyChecker.java
+++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GerritPublicKeyChecker.java
@@ -237,7 +237,7 @@
private static String missingUserIds(Set<String> allowedUserIds) {
StringBuilder sb =
new StringBuilder(
- "Key must contain a valid" + " certification for one of the following identities:\n");
+ "Key must contain a valid certification for one of the following identities:\n");
Iterator<String> sorted = allowedUserIds.stream().sorted().iterator();
while (sorted.hasNext()) {
sb.append(" ").append(sorted.next());
diff --git a/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GpgModule.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GpgModule.java
index 6d93184..d12e921 100644
--- a/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GpgModule.java
+++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/GpgModule.java
@@ -39,7 +39,7 @@
bindConstant().annotatedWith(EnableSignedPush.class).to(enableSignedPush);
if (configEnableSignedPush && !havePgp) {
- log.info("Bouncy Castle PGP not installed; signed push verification is" + " disabled");
+ log.info("Bouncy Castle PGP not installed; signed push verification is disabled");
}
if (enableSignedPush) {
install(new SignedPushModule());
diff --git a/gerrit-gpg/src/test/java/com/google/gerrit/gpg/GerritPublicKeyCheckerTest.java b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/GerritPublicKeyCheckerTest.java
index 011f54b..420dd50 100644
--- a/gerrit-gpg/src/test/java/com/google/gerrit/gpg/GerritPublicKeyCheckerTest.java
+++ b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/GerritPublicKeyCheckerTest.java
@@ -229,7 +229,7 @@
assertProblems(
checker.check(key.getPublicKey()),
Status.BAD,
- "No identities found for user; check" + " http://test/#/settings/web-identities");
+ "No identities found for user; check http://test/#/settings/web-identities");
checker = checkerFactory.create().setStore(store).disableTrust();
assertProblems(
diff --git a/gerrit-gpg/src/test/java/com/google/gerrit/gpg/PublicKeyCheckerTest.java b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/PublicKeyCheckerTest.java
index 5da23a5..39e2cb4 100644
--- a/gerrit-gpg/src/test/java/com/google/gerrit/gpg/PublicKeyCheckerTest.java
+++ b/gerrit-gpg/src/test/java/com/google/gerrit/gpg/PublicKeyCheckerTest.java
@@ -197,7 +197,7 @@
add(validKeyWithoutExpiration());
save();
- assertProblems(k, "Key is revoked (key material has been compromised):" + " test6 compromised");
+ assertProblems(k, "Key is revoked (key material has been compromised): test6 compromised");
PGPPublicKeyRing kr = removeRevokers(k.getPublicKeyRing());
store.add(kr);
@@ -227,7 +227,7 @@
TestKey k = add(revokedCompromisedKey());
save();
- assertProblems(k, "Key is revoked (key material has been compromised):" + " test6 compromised");
+ assertProblems(k, "Key is revoked (key material has been compromised): test6 compromised");
}
@Test
diff --git a/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/SafeHtml.java b/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/SafeHtml.java
index 51a5a0c..9161652 100644
--- a/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/SafeHtml.java
+++ b/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/SafeHtml.java
@@ -126,10 +126,9 @@
/** Convert bare http:// and https:// URLs into <a href> tags. */
public SafeHtml linkify() {
- final String part =
- "(?:" + "[a-zA-Z0-9$_+!*'%;:@=?#/~-]" + "|&(?!lt;|gt;)" + "|[.,](?!(?:\\s|$))" + ")";
+ final String part = "(?:[a-zA-Z0-9$_+!*'%;:@=?#/~-]|&(?!lt;|gt;)|[.,](?!(?:\\s|$)))";
return replaceAll(
- "(https?://" + part + "{2,}" + "(?:[(]" + part + "*" + "[)])*" + part + "*" + ")",
+ "(https?://" + part + "{2,}(?:[(]" + part + "*[)])*" + part + "*)",
"<a href=\"$1\" target=\"_blank\" rel=\"nofollow\">$1</a>");
}
diff --git a/gerrit-gwtexpui/src/test/java/com/google/gwtexpui/safehtml/client/SafeHtml_ReplaceTest.java b/gerrit-gwtexpui/src/test/java/com/google/gwtexpui/safehtml/client/SafeHtml_ReplaceTest.java
index 19e707a..ac0f6fd6 100644
--- a/gerrit-gwtexpui/src/test/java/com/google/gwtexpui/safehtml/client/SafeHtml_ReplaceTest.java
+++ b/gerrit-gwtexpui/src/test/java/com/google/gwtexpui/safehtml/client/SafeHtml_ReplaceTest.java
@@ -54,8 +54,7 @@
o.replaceAll(repls(new RawFindReplace("(issue\\s(\\d+))", "<a href=\"?$2\">$1</a>")));
assertThat(o).isNotSameAs(n);
assertThat(n.asString())
- .isEqualTo(
- "A\n" + "<a href=\"?42\">issue 42</a>\n" + "<a href=\"?9918\">issue 9918</a>\n" + "B");
+ .isEqualTo("A\n<a href=\"?42\">issue 42</a>\n<a href=\"?9918\">issue 9918</a>\nB");
}
@Test
diff --git a/gerrit-gwtexpui/src/test/java/com/google/gwtexpui/safehtml/client/SafeHtml_WikifyPreformatTest.java b/gerrit-gwtexpui/src/test/java/com/google/gwtexpui/safehtml/client/SafeHtml_WikifyPreformatTest.java
index 2544c68..1346cda 100644
--- a/gerrit-gwtexpui/src/test/java/com/google/gwtexpui/safehtml/client/SafeHtml_WikifyPreformatTest.java
+++ b/gerrit-gwtexpui/src/test/java/com/google/gwtexpui/safehtml/client/SafeHtml_WikifyPreformatTest.java
@@ -32,7 +32,7 @@
final SafeHtml n = o.wikify();
assertThat(o).isNotSameAs(n);
assertThat(n.asString())
- .isEqualTo("<p>A</p>" + "<p>" + pre(" This is pre") + pre(" formatted") + "</p>");
+ .isEqualTo("<p>A</p><p>" + pre(" This is pre") + pre(" formatted") + "</p>");
}
@Test
@@ -72,7 +72,7 @@
final SafeHtml n = o.wikify();
assertThat(o).isNotSameAs(n);
assertThat(n.asString())
- .isEqualTo("<p>" + pre(" Q") + pre(" <R>") + pre(" S") + "</p>" + "<p>B</p>");
+ .isEqualTo("<p>" + pre(" Q") + pre(" <R>") + pre(" S") + "</p><p>B</p>");
}
private static SafeHtml html(String text) {
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectBasicAuthFilter.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectBasicAuthFilter.java
index 60482d3..88f9b4c 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectBasicAuthFilter.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectBasicAuthFilter.java
@@ -181,8 +181,7 @@
private boolean failAuthentication(Response rsp, String username) throws IOException {
log.warn(
- "Authentication failed for {}: password does not match the one" + " stored in Gerrit",
- username);
+ "Authentication failed for {}: password does not match the one stored in Gerrit", username);
rsp.sendError(SC_UNAUTHORIZED);
return false;
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/WebSessionManager.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/WebSessionManager.java
index 76ea665..28d12ee 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/WebSessionManager.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/WebSessionManager.java
@@ -71,7 +71,7 @@
if (sessionMaxAgeMillis < MINUTES.toMillis(5)) {
log.warn(
String.format(
- "cache.%s.maxAge is set to %d milliseconds;" + " it should be at least 5 minutes.",
+ "cache.%s.maxAge is set to %d milliseconds; it should be at least 5 minutes.",
CACHE_NAME, sessionMaxAgeMillis));
}
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/PrologShell.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/PrologShell.java
index 83bcf4a..5decd68 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/PrologShell.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/PrologShell.java
@@ -69,7 +69,7 @@
com.google.gerrit.common.Version.getVersion());
System.err.println();
System.err.println(
- "(type Ctrl-D or \"halt.\" to exit," + " \"['path/to/file.pl'].\" to load a file)");
+ "(type Ctrl-D or \"halt.\" to exit, \"['path/to/file.pl'].\" to load a file)");
System.err.println();
System.err.flush();
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/BaseInit.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/BaseInit.java
index 43a44cd..ae5a598 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/BaseInit.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/BaseInit.java
@@ -208,7 +208,7 @@
}
return names;
} catch (FileNotFoundException e) {
- log.warn("Couldn't find distribution archive location." + " No plugin will be installed");
+ log.warn("Couldn't find distribution archive location. No plugin will be installed");
return null;
}
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/LibraryDownloader.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/LibraryDownloader.java
index af4c7d8..f434681 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/LibraryDownloader.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/LibraryDownloader.java
@@ -323,7 +323,7 @@
} else if (!ui.yesno(
null /* force an answer */,
- "error: SHA-1 checksum does not match\n" + "Use %s anyway", //
+ "error: SHA-1 checksum does not match\nUse %s anyway", //
dst.getFileName())) {
deleteDst();
throw new Die("aborted by user");
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteProgram.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteProgram.java
index cc9ddf6..279584a 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteProgram.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteProgram.java
@@ -96,8 +96,7 @@
/** Ensures we are running inside of a valid site, otherwise throws a Die. */
protected void mustHaveValidSite() throws Die {
if (!Files.exists(sitePath.resolve("etc").resolve("gerrit.config"))) {
- throw die(
- "not a Gerrit site: '" + getSitePath() + "'\n" + "Perhaps you need to run init first?");
+ throw die("not a Gerrit site: '" + getSitePath() + "'\nPerhaps you need to run init first?");
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/IdentifiedUser.java b/gerrit-server/src/main/java/com/google/gerrit/server/IdentifiedUser.java
index 026e32a..2c4c61c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/IdentifiedUser.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/IdentifiedUser.java
@@ -364,7 +364,7 @@
if (user == null) {
user = "";
}
- user = user + "|" + "account-" + ua.getId().toString();
+ user = user + "|account-" + ua.getId().toString();
return new PersonIdent(name, user + "@" + guessHost(), when, tz);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/StarredChangesUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/StarredChangesUtil.java
index 8c46663..5ca9e19 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/StarredChangesUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/StarredChangesUtil.java
@@ -134,7 +134,7 @@
static IllegalLabelException mutuallyExclusiveLabels(String label1, String label2) {
return new IllegalLabelException(
String.format(
- "The labels %s and %s are mutually exclusive." + " Only one of them can be set.",
+ "The labels %s and %s are mutually exclusive. Only one of them can be set.",
label1, label2));
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/CreateAccount.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/CreateAccount.java
index cf253ff..45f9183 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/CreateAccount.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/CreateAccount.java
@@ -113,7 +113,7 @@
if (!username.matches(Account.USER_NAME_PATTERN)) {
throw new BadRequestException(
- "Username '" + username + "'" + " must contain only letters, numbers, _, - or .");
+ "Username '" + username + "' must contain only letters, numbers, _, - or .");
}
Set<AccountGroup.Id> groups = parseGroups(input.groups);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteWatchedProjects.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteWatchedProjects.java
index b3a99eb..97102a2 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteWatchedProjects.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteWatchedProjects.java
@@ -53,7 +53,7 @@
throws AuthException, UnprocessableEntityException, OrmException, IOException,
ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException("It is not allowed to edit project watches " + "of other users");
+ throw new AuthException("It is not allowed to edit project watches of other users");
}
if (input == null) {
return Response.none();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/GetWatchedProjects.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/GetWatchedProjects.java
index f61704a..e0aeee0 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/GetWatchedProjects.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/GetWatchedProjects.java
@@ -52,7 +52,7 @@
public List<ProjectWatchInfo> apply(AccountResource rsrc)
throws OrmException, AuthException, IOException, ConfigInvalidException {
if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException("It is not allowed to list project watches " + "of other users");
+ throw new AuthException("It is not allowed to list project watches of other users");
}
Account.Id accountId = rsrc.getUser().getAccountId();
List<ProjectWatchInfo> projectWatchInfos = new ArrayList<>();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/args4j/ChangeIdHandler.java b/gerrit-server/src/main/java/com/google/gerrit/server/args4j/ChangeIdHandler.java
index fe2a94b..bdf0c91 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/args4j/ChangeIdHandler.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/args4j/ChangeIdHandler.java
@@ -50,7 +50,7 @@
final String[] tokens = token.split(",");
if (tokens.length != 3) {
throw new CmdLineException(
- owner, "change should be specified as " + "<project>,<branch>,<change-id>");
+ owner, "change should be specified as <project>,<branch>,<change-id>");
}
try {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/auth/UniversalAuthBackend.java b/gerrit-server/src/main/java/com/google/gerrit/server/auth/UniversalAuthBackend.java
index b0360e4..3ad97b0 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/auth/UniversalAuthBackend.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/auth/UniversalAuthBackend.java
@@ -57,7 +57,7 @@
String msg =
String.format(
- "Multiple AuthBackends attempted to handle request:" + " authUsers=%s authExs=%s",
+ "Multiple AuthBackends attempted to handle request: authUsers=%s authExs=%s",
authUsers, authExs);
throw new AuthException(msg);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java
index 2225460..fbb2115 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java
@@ -377,7 +377,7 @@
@Option(
name = "--base",
aliases = {"-b"},
- usage = "whether to load the content on the base revision instead of the" + " change edit"
+ usage = "whether to load the content on the base revision instead of the change edit"
)
private boolean base;
@@ -478,7 +478,7 @@
@Option(
name = "--base",
aliases = {"-b"},
- usage = "whether to load the message on the base revision instead" + " of the change edit"
+ usage = "whether to load the message on the base revision instead of the change edit"
)
private boolean base;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ConsistencyChecker.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ConsistencyChecker.java
index 1edf9b4..6ee71d9 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ConsistencyChecker.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ConsistencyChecker.java
@@ -374,7 +374,7 @@
if (!rw.isMergedInto(commit, tip)) {
problem(
String.format(
- "Expected merged commit %s is not merged into" + " destination ref %s (%s)",
+ "Expected merged commit %s is not merged into destination ref %s (%s)",
commit.name(), change().getDest().get(), tip.name()));
return;
}
@@ -412,7 +412,7 @@
if (changeId != null && !changeId.equals(change().getKey().get())) {
problem(
String.format(
- "Expected merged commit %s has Change-Id: %s," + " but expected %s",
+ "Expected merged commit %s has Change-Id: %s, but expected %s",
commit.name(), changeId, change().getKey().get()));
return;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
index d0c0e29..e060f8d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
@@ -552,7 +552,7 @@
if (description == null) {
throw new BadRequestException(
String.format(
- "A description is required " + "for the suggested fix of the robot comment on %s",
+ "A description is required for the suggested fix of the robot comment on %s",
commentPath));
}
}
@@ -586,7 +586,7 @@
if (replacementPath == null) {
throw new BadRequestException(
String.format(
- "A file path must be given " + "for the replacement of the robot comment on %s",
+ "A file path must be given for the replacement of the robot comment on %s",
commentPath));
}
}
@@ -608,8 +608,7 @@
if (range == null) {
throw new BadRequestException(
String.format(
- "A range must be given " + "for the replacement of the robot comment on %s",
- commentPath));
+ "A range must be given for the replacement of the robot comment on %s", commentPath));
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PreviewSubmit.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PreviewSubmit.java
index 8b71eca..67c0a6a 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PreviewSubmit.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PreviewSubmit.java
@@ -152,7 +152,7 @@
}
} catch (LimitExceededException e) {
throw new NotImplementedException(
- "The bundle is too big to " + "generate at the server");
+ "The bundle is too big to generate at the server");
}
}
};
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/RebaseUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/RebaseUtil.java
index 88fc1b3..173f522 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/RebaseUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/RebaseUtil.java
@@ -164,7 +164,7 @@
throw new UnprocessableEntityException("Cannot rebase a change with multiple parents.");
} else if (commit.getParentCount() == 0) {
throw new UnprocessableEntityException(
- "Cannot rebase a change without any parents" + " (is this the initial commit?).");
+ "Cannot rebase a change without any parents (is this the initial commit?).");
}
RevId parentRev = new RevId(commit.getParent(0).name());
@@ -184,7 +184,7 @@
if (depChange.getStatus().isOpen()) {
if (depPatchSet.getId().equals(depChange.currentPatchSetId())) {
throw new ResourceConflictException(
- "Change is already based on the latest patch set of the" + " dependent change.");
+ "Change is already based on the latest patch set of the dependent change.");
}
baseRev = cd.currentPatchSet().getRevision().get();
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java
index 8013d87..64e02a8 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java
@@ -318,7 +318,7 @@
cs = mergeSuperSet.get().completeChangeSet(db, cd.change(), resource.getControl().getUser());
} catch (OrmException | IOException e) {
throw new OrmRuntimeException(
- "Could not determine complete set of " + "changes to be submitted", e);
+ "Could not determine complete set of changes to be submitted", e);
}
int topicSize = 0;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/edit/ChangeEditModifier.java b/gerrit-server/src/main/java/com/google/gerrit/server/edit/ChangeEditModifier.java
index 4a7f7da..3d1fb79 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/edit/ChangeEditModifier.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/edit/ChangeEditModifier.java
@@ -111,7 +111,7 @@
Optional<ChangeEdit> changeEdit = lookupChangeEdit(changeControl);
if (changeEdit.isPresent()) {
throw new InvalidChangeOperationException(
- String.format("A change edit " + "already exists for change %s", changeControl.getId()));
+ String.format("A change edit already exists for change %s", changeControl.getId()));
}
PatchSet currentPatchSet = lookupCurrentPatchSet(changeControl);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/events/EventFactory.java b/gerrit-server/src/main/java/com/google/gerrit/server/events/EventFactory.java
index 3de1243..80dcb78 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/events/EventFactory.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/events/EventFactory.java
@@ -150,7 +150,7 @@
try {
a.commitMessage = changeDataFactory.create(db, change).commitMessage();
} catch (Exception e) {
- log.error("Error while getting full commit message for" + " change " + a.number);
+ log.error("Error while getting full commit message for change " + a.number);
}
a.url = getChangeUrl(change);
a.owner = asAccountAttribute(change.getOwner());
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/BatchUpdateReviewDb.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/BatchUpdateReviewDb.java
index 1f476fa..084b2e1 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/BatchUpdateReviewDb.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/BatchUpdateReviewDb.java
@@ -93,7 +93,7 @@
@Override
public Change atomicUpdate(Change.Id key, AtomicUpdate<Change> update) {
throw new UnsupportedOperationException(
- "do not call atomicUpdate; updateChange is always called within a" + " transaction");
+ "do not call atomicUpdate; updateChange is always called within a transaction");
}
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
index 3da17a4..deea815 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
@@ -268,7 +268,7 @@
} else if (results.isEmpty()) {
throw new IllegalStateException(
String.format(
- "SubmitRuleEvaluator.evaluate for change %s " + "returned empty list for %s in %s",
+ "SubmitRuleEvaluator.evaluate for change %s returned empty list for %s in %s",
cd.getId(), patchSet.getId(), cd.change().getProject().get()));
}
@@ -733,7 +733,7 @@
try {
return orm.openRepo(project);
} catch (NoSuchProjectException noProject) {
- logWarn("Project " + noProject.project() + " no longer exists, " + "abandoning open changes");
+ logWarn("Project " + noProject.project() + " no longer exists, abandoning open changes");
abandonAllOpenChangeForDeletedProject(noProject.project());
} catch (IOException e) {
throw new IntegrationException("Error opening project " + project, e);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/MultiProgressMonitor.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/MultiProgressMonitor.java
index a994af0..9101b44 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/MultiProgressMonitor.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/MultiProgressMonitor.java
@@ -236,7 +236,7 @@
if (!done && workerFuture.isDone()) {
// The worker may not have called end() explicitly, which is likely a
// programming error.
- log.warn("MultiProgressMonitor worker did not call end()" + " before returning");
+ log.warn("MultiProgressMonitor worker did not call end() before returning");
end();
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index aed59e7..a6c35ed 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -197,7 +197,7 @@
UPDATE(
"You are not allowed to perform this operation.\n"
+ "To push into this reference you need 'Push' rights."),
- DELETE("You need 'Push' rights with the 'Force Push'\n" + "flag set to delete references."),
+ DELETE("You need 'Push' rights with the 'Force Push'\nflag set to delete references."),
DELETE_CHANGES("Cannot delete from '" + REFS_CHANGES + "'"),
CODE_REVIEW(
"You need 'Push' rights to upload code review requests.\n"
@@ -762,7 +762,7 @@
String refName = replace.inputCommand.getRefName();
checkState(
NEW_PATCHSET.matcher(refName).matches(),
- "expected a new patch set command as input when creating %s;" + " got %s",
+ "expected a new patch set command as input when creating %s; got %s",
replace.cmd.getRefName(),
refName);
try {
@@ -2845,7 +2845,7 @@
}
logDebug(
- "Auto-closing {} changes with existing patch sets and {} with" + " new patch sets",
+ "Auto-closing {} changes with existing patch sets and {} with new patch sets",
existingPatchSets,
newPatchSets);
bu.execute();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java
index 5ed3f97..cdb2c3b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java
@@ -530,7 +530,7 @@
}
} catch (IOException e) {
throw new SubmoduleException(
- "Could not perform a revwalk to " + "create superproject commit message", e);
+ "Could not perform a revwalk to create superproject commit message", e);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java
index a84ab31..150965c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java
@@ -75,7 +75,7 @@
private static final String INVALID_CONFIG =
"Change contains an invalid project configuration.";
private static final String PARENT_NOT_FOUND =
- "Change contains an invalid project configuration:\n" + "Parent project does not exist.";
+ "Change contains an invalid project configuration:\nParent project does not exist.";
private static final String PLUGIN_VALUE_NOT_EDITABLE =
"Change contains an invalid project configuration:\n"
+ "One of the plugin configuration parameters is not editable.";
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/change/IndexedChangeQuery.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/change/IndexedChangeQuery.java
index ff35750..f99f3b4 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/change/IndexedChangeQuery.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/change/IndexedChangeQuery.java
@@ -122,7 +122,7 @@
Predicate<ChangeData> pred = getChild(0);
checkState(
pred.isMatchable(),
- "match invoked, but child predicate %s " + "doesn't implement %s",
+ "match invoked, but child predicate %s doesn't implement %s",
pred,
Matchable.class.getName());
return pred.asMatchable().match(cd);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/Pop3MailReceiver.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/Pop3MailReceiver.java
index 3bf452f..e8e2250 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/Pop3MailReceiver.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/Pop3MailReceiver.java
@@ -65,7 +65,7 @@
try {
try {
if (!pop3.login(mailSettings.username, mailSettings.password)) {
- log.error("Could not login to POP3 email server." + " Check username and password");
+ log.error("Could not login to POP3 email server. Check username and password");
return;
}
try {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/ChangeEmail.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/ChangeEmail.java
index fb9564a0..fbecaef 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/ChangeEmail.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/ChangeEmail.java
@@ -207,7 +207,7 @@
}
public String getChangeMessageThreadId() throws EmailException {
- return velocify("<gerrit.${change.createdOn.time}.$change.key.get()" + "@$email.gerritHost>");
+ return velocify("<gerrit.${change.createdOn.time}.$change.key.get()@$email.gerritHost>");
}
/** Format the sender's "cover letter", {@link #getCoverLetter()}. */
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/SmtpEmailSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/SmtpEmailSender.java
index 841c995..80e6bb8 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/SmtpEmailSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/SmtpEmailSender.java
@@ -192,7 +192,7 @@
setMissingHeader(
hdrs,
"Content-Type",
- "multipart/alternative; " + "boundary=\"" + boundary + "\"; " + "charset=UTF-8");
+ "multipart/alternative; boundary=\"" + boundary + "\"; charset=UTF-8");
encodedBody = buildMultipartBody(boundary, textBody, htmlBody);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/AbstractChangeUpdate.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/AbstractChangeUpdate.java
index 8df9bd6..472eda1 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/AbstractChangeUpdate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/AbstractChangeUpdate.java
@@ -29,8 +29,10 @@
import com.google.gerrit.server.project.ChangeControl;
import com.google.gwtorm.server.OrmException;
import java.io.IOException;
+import java.sql.Timestamp;
import java.util.Date;
import org.eclipse.jgit.lib.CommitBuilder;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
@@ -47,15 +49,17 @@
protected final Account.Id realAccountId;
protected final PersonIdent authorIdent;
protected final Date when;
+ private final long readOnlySkewMs;
@Nullable private final ChangeNotes notes;
private final Change change;
- private final PersonIdent serverIdent;
+ protected final PersonIdent serverIdent;
protected PatchSet.Id psId;
private ObjectId result;
protected AbstractChangeUpdate(
+ Config cfg,
NotesMigration migration,
ChangeControl ctl,
PersonIdent serverIdent,
@@ -73,9 +77,11 @@
this.realAccountId = realAccountId != null ? realAccountId : accountId;
this.authorIdent = ident(noteUtil, serverIdent, anonymousCowardName, ctl.getUser(), when);
this.when = when;
+ this.readOnlySkewMs = NoteDbChangeState.getReadOnlySkew(cfg);
}
protected AbstractChangeUpdate(
+ Config cfg,
NotesMigration migration,
ChangeNoteUtil noteUtil,
PersonIdent serverIdent,
@@ -99,6 +105,7 @@
this.realAccountId = realAccountId;
this.authorIdent = authorIdent;
this.when = when;
+ this.readOnlySkewMs = NoteDbChangeState.getReadOnlySkew(cfg);
}
private static void checkUserType(CurrentUser user) {
@@ -133,6 +140,14 @@
return change.getId();
}
+ /**
+ * @return notes for the state of this change prior to this update. If this update is part of a
+ * series managed by a {@link NoteDbUpdateManager}, then this reflects the state prior to the
+ * first update in the series. A null return value can only happen when the change is being
+ * rebuilt from NoteDb. A change that is in the process of being created will result in a
+ * non-null return value from this method, but a null return value from {@link
+ * ChangeNotes#getRevision()}.
+ */
@Nullable
public ChangeNotes getNotes() {
return notes;
@@ -206,6 +221,7 @@
// to actually store.
checkArgument(rw.getObjectReader().getCreatedFromInserter() == ins);
+ checkNotReadOnly();
ObjectId z = ObjectId.zeroId();
CommitBuilder cb = applyImpl(rw, ins, curr);
if (cb == null) {
@@ -233,6 +249,18 @@
return result;
}
+ protected void checkNotReadOnly() throws OrmException {
+ ChangeNotes notes = getNotes();
+ if (notes == null) {
+ // Can only happen during ChangeRebuilder, which will never include a read-only lease.
+ return;
+ }
+ Timestamp until = notes.getReadOnlyUntil();
+ if (until != null && NoteDbChangeState.timeForReadOnlyCheck(readOnlySkewMs).before(until)) {
+ throw new OrmException("change " + notes.getChangeId() + " is read-only until " + until);
+ }
+ }
+
/**
* Create a commit containing the contents of this update.
*
@@ -267,7 +295,7 @@
checkArgument(c.revId != null, "RevId required for comment: %s", c);
checkArgument(
c.author.getId().equals(getAccountId()),
- "The author for the following comment does not match the author of" + " this %s (%s): %s",
+ "The author for the following comment does not match the author of this %s (%s): %s",
getClass().getSimpleName(),
getAccountId(),
c);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeDraftUpdate.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeDraftUpdate.java
index 74ffb96..428faef 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeDraftUpdate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeDraftUpdate.java
@@ -29,6 +29,7 @@
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.AnonymousCowardName;
+import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gwtorm.server.OrmException;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
@@ -42,6 +43,7 @@
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.CommitBuilder;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
@@ -91,6 +93,7 @@
@AssistedInject
private ChangeDraftUpdate(
+ @GerritServerConfig Config cfg,
@GerritPersonIdent PersonIdent serverIdent,
@AnonymousCowardName String anonymousCowardName,
NotesMigration migration,
@@ -102,6 +105,7 @@
@Assisted PersonIdent authorIdent,
@Assisted Date when) {
super(
+ cfg,
migration,
noteUtil,
serverIdent,
@@ -117,6 +121,7 @@
@AssistedInject
private ChangeDraftUpdate(
+ @GerritServerConfig Config cfg,
@GerritPersonIdent PersonIdent serverIdent,
@AnonymousCowardName String anonymousCowardName,
NotesMigration migration,
@@ -128,6 +133,7 @@
@Assisted PersonIdent authorIdent,
@Assisted Date when) {
super(
+ cfg,
migration,
noteUtil,
serverIdent,
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNoteUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNoteUtil.java
index 8d61c36..c848987 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNoteUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNoteUtil.java
@@ -73,6 +73,7 @@
public static final FooterKey FOOTER_PATCH_SET = new FooterKey("Patch-set");
public static final FooterKey FOOTER_PATCH_SET_DESCRIPTION =
new FooterKey("Patch-set-description");
+ public static final FooterKey FOOTER_READ_ONLY_UNTIL = new FooterKey("Read-only-until");
public static final FooterKey FOOTER_REAL_USER = new FooterKey("Real-user");
public static final FooterKey FOOTER_STATUS = new FooterKey("Status");
public static final FooterKey FOOTER_SUBJECT = new FooterKey("Subject");
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotes.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotes.java
index b15874d..4993a5d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotes.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotes.java
@@ -63,6 +63,7 @@
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
+import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -166,7 +167,7 @@
checkNotNull(change, "change %s not found in ReviewDb", changeId);
checkArgument(
change.getProject().equals(project),
- "passed project %s when creating ChangeNotes for %s, but actual" + " project is %s",
+ "passed project %s when creating ChangeNotes for %s, but actual project is %s",
project,
changeId,
change.getProject());
@@ -216,7 +217,7 @@
private ChangeNotes createFromChangeOnlyWhenNoteDbDisabled(Change change) throws OrmException {
checkState(
!args.migration.readChanges(),
- "do not call" + " createFromChangeWhenNoteDbDisabled when NoteDb is enabled");
+ "do not call createFromChangeWhenNoteDbDisabled when NoteDb is enabled");
return new ChangeNotes(args, change).load();
}
@@ -326,15 +327,14 @@
Change change = readOneReviewDbChange(db, id);
if (change == null) {
if (defaultStorage == PrimaryStorage.REVIEW_DB) {
- log.warn(
- "skipping change {} found in project {} " + "but not in ReviewDb", id, project);
+ log.warn("skipping change {} found in project {} but not in ReviewDb", id, project);
continue;
}
// TODO(dborowitz): See discussion in BatchUpdate#newChangeContext.
change = newNoteDbOnlyChange(project, id);
} else if (!change.getProject().equals(project)) {
log.error(
- "skipping change {} found in project {} " + "because ReviewDb change has project {}",
+ "skipping change {} found in project {} because ReviewDb change has project {}",
id,
project,
change.getProject());
@@ -558,6 +558,11 @@
return checkNotNull(getPatchSets().get(psId), "missing current patch set %s", psId.get());
}
+ @VisibleForTesting
+ public Timestamp getReadOnlyUntil() {
+ return state.readOnlyUntil();
+ }
+
@Override
protected void onLoad(LoadHandle handle)
throws NoSuchChangeException, IOException, ConfigInvalidException {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesParser.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesParser.java
index 2a9d985..dac999c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesParser.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesParser.java
@@ -24,6 +24,7 @@
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_LABEL;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_PATCH_SET;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_PATCH_SET_DESCRIPTION;
+import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_READ_ONLY_UNTIL;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_REAL_USER;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_STATUS;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_SUBJECT;
@@ -68,6 +69,7 @@
import java.io.IOException;
import java.nio.charset.Charset;
import java.sql.Timestamp;
+import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -76,6 +78,7 @@
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@@ -89,6 +92,7 @@
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.notes.NoteMap;
import org.eclipse.jgit.revwalk.FooterKey;
+import org.eclipse.jgit.util.GitDateParser;
import org.eclipse.jgit.util.RawParseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -152,6 +156,7 @@
private String submissionId;
private String tag;
private RevisionNoteMap<ChangeRevisionNote> revisionNoteMap;
+ private Timestamp readOnlyUntil;
ChangeNotesParser(
Change.Id changeId,
@@ -232,7 +237,8 @@
submitRecords,
buildAllMessages(),
buildMessagesByPatchSet(),
- comments);
+ comments,
+ readOnlyUntil);
}
private PatchSet.Id buildCurrentPatchSetId() {
@@ -369,6 +375,10 @@
// behavior.
}
+ if (readOnlyUntil == null) {
+ parseReadOnlyUntil(commit);
+ }
+
if (lastUpdatedOn == null || ts.after(lastUpdatedOn)) {
lastUpdatedOn = ts;
}
@@ -900,6 +910,20 @@
}
}
+ private void parseReadOnlyUntil(ChangeNotesCommit commit) throws ConfigInvalidException {
+ String raw = parseOneFooter(commit, FOOTER_READ_ONLY_UNTIL);
+ if (raw == null) {
+ return;
+ }
+ try {
+ readOnlyUntil = new Timestamp(GitDateParser.parse(raw, null, Locale.US).getTime());
+ } catch (ParseException e) {
+ ConfigInvalidException cie = invalidFooter(FOOTER_READ_ONLY_UNTIL, raw);
+ cie.initCause(e);
+ throw cie;
+ }
+ }
+
private void pruneReviewers() {
Iterator<Table.Cell<Account.Id, ReviewerStateInternal, Timestamp>> rit =
reviewers.cellSet().iterator();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesState.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesState.java
index 62df01b..7b25bbd 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesState.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesState.java
@@ -70,7 +70,8 @@
ImmutableList.of(),
ImmutableList.of(),
ImmutableListMultimap.of(),
- ImmutableListMultimap.of());
+ ImmutableListMultimap.of(),
+ null);
}
static ChangeNotesState create(
@@ -98,7 +99,8 @@
List<SubmitRecord> submitRecords,
List<ChangeMessage> allChangeMessages,
ListMultimap<PatchSet.Id, ChangeMessage> changeMessagesByPatchSet,
- ListMultimap<RevId, Comment> publishedComments) {
+ ListMultimap<RevId, Comment> publishedComments,
+ @Nullable Timestamp readOnlyUntil) {
if (hashtags == null) {
hashtags = ImmutableSet.of();
}
@@ -128,7 +130,8 @@
ImmutableList.copyOf(submitRecords),
ImmutableList.copyOf(allChangeMessages),
ImmutableListMultimap.copyOf(changeMessagesByPatchSet),
- ImmutableListMultimap.copyOf(publishedComments));
+ ImmutableListMultimap.copyOf(publishedComments),
+ readOnlyUntil);
}
/**
@@ -206,6 +209,9 @@
abstract ImmutableListMultimap<RevId, Comment> publishedComments();
+ @Nullable
+ abstract Timestamp readOnlyUntil();
+
Change newChange(Project.NameKey project) {
ChangeColumns c = checkNotNull(columns(), "columns are required");
Change change =
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeUpdate.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeUpdate.java
index c241965..7af0cb4 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeUpdate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeUpdate.java
@@ -29,6 +29,7 @@
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_LABEL;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_PATCH_SET;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_PATCH_SET_DESCRIPTION;
+import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_READ_ONLY_UNTIL;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_REAL_USER;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_STATUS;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_SUBJECT;
@@ -58,6 +59,7 @@
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.config.AnonymousCowardName;
+import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.util.LabelVote;
@@ -67,6 +69,7 @@
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import java.io.IOException;
+import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
@@ -79,6 +82,7 @@
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.CommitBuilder;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
@@ -144,12 +148,14 @@
private boolean isAllowWriteToNewtRef;
private String psDescription;
private boolean currentPatchSet;
+ private Timestamp readOnlyUntil;
private ChangeDraftUpdate draftUpdate;
private RobotCommentUpdate robotCommentUpdate;
@AssistedInject
private ChangeUpdate(
+ @GerritServerConfig Config cfg,
@GerritPersonIdent PersonIdent serverIdent,
@AnonymousCowardName String anonymousCowardName,
NotesMigration migration,
@@ -161,6 +167,7 @@
@Assisted ChangeControl ctl,
ChangeNoteUtil noteUtil) {
this(
+ cfg,
serverIdent,
anonymousCowardName,
migration,
@@ -176,6 +183,7 @@
@AssistedInject
private ChangeUpdate(
+ @GerritServerConfig Config cfg,
@GerritPersonIdent PersonIdent serverIdent,
@AnonymousCowardName String anonymousCowardName,
NotesMigration migration,
@@ -188,6 +196,7 @@
@Assisted Date when,
ChangeNoteUtil noteUtil) {
this(
+ cfg,
serverIdent,
anonymousCowardName,
migration,
@@ -212,6 +221,7 @@
@AssistedInject
private ChangeUpdate(
+ @GerritServerConfig Config cfg,
@GerritPersonIdent PersonIdent serverIdent,
@AnonymousCowardName String anonymousCowardName,
NotesMigration migration,
@@ -223,7 +233,7 @@
@Assisted Date when,
@Assisted Comparator<String> labelNameComparator,
ChangeNoteUtil noteUtil) {
- super(migration, ctl, serverIdent, anonymousCowardName, noteUtil, when);
+ super(cfg, migration, ctl, serverIdent, anonymousCowardName, noteUtil, when);
this.accountCache = accountCache;
this.draftUpdateFactory = draftUpdateFactory;
this.robotCommentUpdateFactory = robotCommentUpdateFactory;
@@ -233,6 +243,7 @@
@AssistedInject
private ChangeUpdate(
+ @GerritServerConfig Config cfg,
@GerritPersonIdent PersonIdent serverIdent,
@AnonymousCowardName String anonymousCowardName,
NotesMigration migration,
@@ -248,6 +259,7 @@
@Assisted Date when,
@Assisted Comparator<String> labelNameComparator) {
super(
+ cfg,
migration,
noteUtil,
serverIdent,
@@ -695,6 +707,10 @@
addIdent(msg, realAccountId).append('\n');
}
+ if (readOnlyUntil != null) {
+ addFooter(msg, FOOTER_READ_ONLY_UNTIL, ChangeNoteUtil.formatTime(serverIdent, readOnlyUntil));
+ }
+
cb.setMessage(msg.toString());
try {
ObjectId treeId = storeRevisionNotes(rw, ins, curr);
@@ -740,7 +756,8 @@
&& groups == null
&& tag == null
&& psDescription == null
- && !currentPatchSet;
+ && !currentPatchSet
+ && readOnlyUntil == null;
}
ChangeDraftUpdate getDraftUpdate() {
@@ -760,6 +777,10 @@
return isAllowWriteToNewtRef;
}
+ void setReadOnlyUntil(Timestamp readOnlyUntil) {
+ this.readOnlyUntil = readOnlyUntil;
+ }
+
private static StringBuilder addFooter(StringBuilder sb, FooterKey footer) {
return sb.append(footer.getName()).append(": ");
}
@@ -782,4 +803,13 @@
sb.append('>');
return sb;
}
+
+ @Override
+ protected void checkNotReadOnly() throws OrmException {
+ // Allow setting Read-only-until to 0 to release an existing lease.
+ if (readOnlyUntil != null && readOnlyUntil.getTime() == 0) {
+ return;
+ }
+ super.checkNotReadOnly();
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbChangeState.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbChangeState.java
index 1350a1f..fef7fdf 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbChangeState.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbChangeState.java
@@ -301,7 +301,7 @@
return cfg.getTimeUnit("notedb", null, "maxTimestampSkew", 1000, TimeUnit.MILLISECONDS);
}
- private static Timestamp timeForReadOnlyCheck(long skewMs) {
+ static Timestamp timeForReadOnlyCheck(long skewMs) {
// Subtract some slop in case the machine that set the change's read-only
// lease has a clock behind ours.
return new Timestamp(TimeUtil.nowMs() - skewMs);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbModule.java
index 0b01e14..d249689 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbModule.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbModule.java
@@ -19,6 +19,7 @@
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Change.Id;
+import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.notedb.NoteDbUpdateManager.Result;
import com.google.gerrit.server.notedb.rebuild.ChangeRebuilder;
@@ -95,6 +96,11 @@
public void buildUpdates(NoteDbUpdateManager manager, ChangeBundle bundle) {
// Do nothing.
}
+
+ @Override
+ public void rebuildReviewDb(ReviewDb db, Project.NameKey project, Id changeId) {
+ // Do nothing.
+ }
});
bind(new TypeLiteral<Cache<ChangeNotesCache.Key, ChangeNotesState>>() {})
.annotatedWith(Names.named(ChangeNotesCache.CACHE_NAME))
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbUpdateManager.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbUpdateManager.java
index cc738e5..37b730f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbUpdateManager.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/NoteDbUpdateManager.java
@@ -527,7 +527,7 @@
private MismatchedStateException(Change.Id id, NoteDbChangeState expectedState) {
super(
String.format(
- "cannot apply NoteDb updates for change %s;" + " change meta ref does not match %s",
+ "cannot apply NoteDb updates for change %s; change meta ref does not match %s",
id, expectedState.getChangeMetaId().name()));
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/PrimaryStorageMigrator.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/PrimaryStorageMigrator.java
index 10345c8..0995c2d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/PrimaryStorageMigrator.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/PrimaryStorageMigrator.java
@@ -26,18 +26,32 @@
import com.github.rholder.retry.WaitStrategies;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Stopwatch;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.TimeUtil;
+import com.google.gerrit.extensions.restapi.RestApiException;
+import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.reviewdb.server.ReviewDbUtil;
+import com.google.gerrit.server.InternalUser;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.git.BatchUpdate;
+import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.RepoRefCache;
+import com.google.gerrit.server.git.UpdateException;
+import com.google.gerrit.server.index.change.ChangeField;
import com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage;
+import com.google.gerrit.server.notedb.NoteDbChangeState.RefState;
import com.google.gerrit.server.notedb.rebuild.ChangeRebuilder;
+import com.google.gerrit.server.project.ChangeControl;
+import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gwtorm.server.AtomicUpdate;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.OrmRuntimeException;
@@ -46,11 +60,17 @@
import com.google.inject.Singleton;
import java.io.IOException;
import java.sql.Timestamp;
+import java.util.List;
import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,10 +80,15 @@
public class PrimaryStorageMigrator {
private static final Logger log = LoggerFactory.getLogger(PrimaryStorageMigrator.class);
- private final Provider<ReviewDb> db;
- private final GitRepositoryManager repoManager;
private final AllUsersName allUsers;
+ private final BatchUpdate.Factory batchUpdateFactory;
+ private final ChangeControl.GenericFactory changeControlFactory;
private final ChangeRebuilder rebuilder;
+ private final ChangeUpdate.Factory updateFactory;
+ private final GitRepositoryManager repoManager;
+ private final InternalUser.Factory internalUserFactory;
+ private final Provider<InternalChangeQuery> queryProvider;
+ private final Provider<ReviewDb> db;
private final long skewMs;
private final long timeoutMs;
@@ -75,8 +100,24 @@
Provider<ReviewDb> db,
GitRepositoryManager repoManager,
AllUsersName allUsers,
- ChangeRebuilder rebuilder) {
- this(cfg, db, repoManager, allUsers, rebuilder, null);
+ ChangeRebuilder rebuilder,
+ ChangeControl.GenericFactory changeControlFactory,
+ Provider<InternalChangeQuery> queryProvider,
+ ChangeUpdate.Factory updateFactory,
+ InternalUser.Factory internalUserFactory,
+ BatchUpdate.Factory batchUpdateFactory) {
+ this(
+ cfg,
+ db,
+ repoManager,
+ allUsers,
+ rebuilder,
+ null,
+ changeControlFactory,
+ queryProvider,
+ updateFactory,
+ internalUserFactory,
+ batchUpdateFactory);
}
@VisibleForTesting
@@ -86,12 +127,22 @@
GitRepositoryManager repoManager,
AllUsersName allUsers,
ChangeRebuilder rebuilder,
- @Nullable Retryer<NoteDbChangeState> testEnsureRebuiltRetryer) {
+ @Nullable Retryer<NoteDbChangeState> testEnsureRebuiltRetryer,
+ ChangeControl.GenericFactory changeControlFactory,
+ Provider<InternalChangeQuery> queryProvider,
+ ChangeUpdate.Factory updateFactory,
+ InternalUser.Factory internalUserFactory,
+ BatchUpdate.Factory batchUpdateFactory) {
this.db = db;
this.repoManager = repoManager;
this.allUsers = allUsers;
this.rebuilder = rebuilder;
this.testEnsureRebuiltRetryer = testEnsureRebuiltRetryer;
+ this.changeControlFactory = changeControlFactory;
+ this.queryProvider = queryProvider;
+ this.updateFactory = updateFactory;
+ this.internalUserFactory = internalUserFactory;
+ this.batchUpdateFactory = batchUpdateFactory;
skewMs = NoteDbChangeState.getReadOnlySkew(cfg);
String s = "notedb";
@@ -189,7 +240,7 @@
// failure.
Stopwatch sw = Stopwatch.createStarted();
- Change readOnlyChange = setReadOnly(id); // MRO
+ Change readOnlyChange = setReadOnlyInReviewDb(id); // MRO
if (readOnlyChange == null) {
return; // Already migrated.
}
@@ -217,7 +268,7 @@
log.info("Migrated change {} to NoteDb primary in {}ms", id, sw.elapsed(MILLISECONDS));
}
- private Change setReadOnly(Change.Id id) throws OrmException {
+ private Change setReadOnlyInReviewDb(Change.Id id) throws OrmException {
AtomicBoolean alreadyMigrated = new AtomicBoolean(false);
Change result =
db().changes()
@@ -316,4 +367,124 @@
private String badState(NoteDbChangeState actual, NoteDbChangeState expected) {
return "state changed unexpectedly: " + actual + " != " + expected;
}
+
+ public void migrateToReviewDbPrimary(Change.Id id, @Nullable Project.NameKey project)
+ throws OrmException, IOException {
+ // Migrating back to ReviewDb primary is much simpler than the original migration to NoteDb
+ // primary, because when NoteDb is primary, each write only goes to one storage location rather
+ // than both. We only need to consider whether a concurrent writer (OR) conflicts with the first
+ // setReadOnlyInNoteDb step (MR) in this method.
+ //
+ // If OR wins, then either:
+ // * MR will set read-only after OR is completed, which is not a concurrent write.
+ // * MR will fail to set read-only with a lock failure. The caller will have to retry, but the
+ // change is not in a read-only state, so behavior is not degraded in the meantime.
+ //
+ // If MR wins, then either:
+ // * OR will fail with a read-only exception (via AbstractChangeNotes#apply).
+ // * OR will fail with a lock failure.
+ //
+ // In all of these scenarios, the change is read-only if and only if MR succeeds.
+ //
+ // There will be no concurrent writes to ReviewDb for this change until
+ // setPrimaryStorageReviewDb completes, because ReviewDb writes are not attempted when primary
+ // storage is NoteDb. After the primary storage changes back, it is possible for subsequent
+ // NoteDb writes to conflict with the releaseReadOnlyLeaseInNoteDb step, but at this point,
+ // since ReviewDb is primary, we are back to ignoring them.
+ Stopwatch sw = Stopwatch.createStarted();
+ if (project == null) {
+ project = getProject(id);
+ }
+ ObjectId newMetaId = setReadOnlyInNoteDb(project, id);
+ rebuilder.rebuildReviewDb(db(), project, id);
+ setPrimaryStorageReviewDb(id, newMetaId);
+ releaseReadOnlyLeaseInNoteDb(project, id);
+ log.info("Migrated change {} to ReviewDb primary in {}ms", id, sw.elapsed(MILLISECONDS));
+ }
+
+ private ObjectId setReadOnlyInNoteDb(Project.NameKey project, Change.Id id)
+ throws OrmException, IOException {
+ Timestamp now = TimeUtil.nowTs();
+ Timestamp until = new Timestamp(now.getTime() + timeoutMs);
+ ChangeUpdate update =
+ updateFactory.create(
+ changeControlFactory.controlFor(db.get(), project, id, internalUserFactory.create()));
+ update.setReadOnlyUntil(until);
+ return update.commit();
+ }
+
+ private void setPrimaryStorageReviewDb(Change.Id id, ObjectId newMetaId)
+ throws OrmException, IOException {
+ ImmutableMap.Builder<Account.Id, ObjectId> draftIds = ImmutableMap.builder();
+ try (Repository repo = repoManager.openRepository(allUsers)) {
+ for (Ref draftRef :
+ repo.getRefDatabase().getRefs(RefNames.refsDraftCommentsPrefix(id)).values()) {
+ Account.Id accountId = Account.Id.fromRef(draftRef.getName());
+ if (accountId != null) {
+ draftIds.put(accountId, draftRef.getObjectId().copy());
+ }
+ }
+ }
+ NoteDbChangeState newState =
+ new NoteDbChangeState(
+ id,
+ PrimaryStorage.REVIEW_DB,
+ Optional.of(RefState.create(newMetaId, draftIds.build())),
+ Optional.empty());
+ db().changes()
+ .atomicUpdate(
+ id,
+ new AtomicUpdate<Change>() {
+ @Override
+ public Change update(Change change) {
+ if (PrimaryStorage.of(change) != PrimaryStorage.NOTE_DB) {
+ throw new OrmRuntimeException(
+ "change " + id + " is not NoteDb primary: " + change.getNoteDbState());
+ }
+ change.setNoteDbState(newState.toString());
+ return change;
+ }
+ });
+ }
+
+ private void releaseReadOnlyLeaseInNoteDb(Project.NameKey project, Change.Id id)
+ throws OrmException {
+ // Use a BatchUpdate since ReviewDb is primary at this point, so it needs to reflect the update.
+ try (BatchUpdate bu =
+ batchUpdateFactory.create(
+ db.get(), project, internalUserFactory.create(), TimeUtil.nowTs())) {
+ bu.addOp(
+ id,
+ new BatchUpdate.Op() {
+ @Override
+ public boolean updateChange(ChangeContext ctx) {
+ ctx.getUpdate(ctx.getChange().currentPatchSetId()).setReadOnlyUntil(new Timestamp(0));
+ return true;
+ }
+ });
+ bu.execute();
+ } catch (RestApiException | UpdateException e) {
+ throw new OrmException(e);
+ }
+ }
+
+ private Project.NameKey getProject(Change.Id id) throws OrmException {
+ List<ChangeData> cds =
+ queryProvider
+ .get()
+ .setRequestedFields(ImmutableSet.of(ChangeField.PROJECT.getName()))
+ .byLegacyChangeId(id);
+ Set<Project.NameKey> projects = new TreeSet<>();
+ for (ChangeData cd : cds) {
+ projects.add(cd.project());
+ }
+ if (projects.size() != 1) {
+ throw new OrmException(
+ "zero or multiple projects found for change "
+ + id
+ + ", must specify project explicitly: "
+ + projects);
+ }
+ return projects.iterator().next();
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/RobotCommentUpdate.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/RobotCommentUpdate.java
index 9ce4b54..82593eb 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/RobotCommentUpdate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/RobotCommentUpdate.java
@@ -26,6 +26,7 @@
import com.google.gerrit.reviewdb.client.RobotComment;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.config.AnonymousCowardName;
+import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gwtorm.server.OrmException;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
@@ -38,6 +39,7 @@
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.CommitBuilder;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
@@ -73,6 +75,7 @@
@AssistedInject
private RobotCommentUpdate(
+ @GerritServerConfig Config cfg,
@GerritPersonIdent PersonIdent serverIdent,
@AnonymousCowardName String anonymousCowardName,
NotesMigration migration,
@@ -83,6 +86,7 @@
@Assisted PersonIdent authorIdent,
@Assisted Date when) {
super(
+ cfg,
migration,
noteUtil,
serverIdent,
@@ -97,6 +101,7 @@
@AssistedInject
private RobotCommentUpdate(
+ @GerritServerConfig Config cfg,
@GerritPersonIdent PersonIdent serverIdent,
@AnonymousCowardName String anonymousCowardName,
NotesMigration migration,
@@ -107,6 +112,7 @@
@Assisted PersonIdent authorIdent,
@Assisted Date when) {
super(
+ cfg,
migration,
noteUtil,
serverIdent,
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/TestChangeRebuilderWrapper.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/TestChangeRebuilderWrapper.java
index 4ee84dc..11fef24 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/TestChangeRebuilderWrapper.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/TestChangeRebuilderWrapper.java
@@ -16,6 +16,8 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.Change.Id;
+import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.notedb.NoteDbUpdateManager.Result;
import com.google.gerrit.server.notedb.rebuild.ChangeRebuilder;
@@ -111,4 +113,13 @@
// Don't check for manual failure; that happens in execute().
delegate.buildUpdates(manager, bundle);
}
+
+ @Override
+ public void rebuildReviewDb(ReviewDb db, Project.NameKey project, Id changeId)
+ throws OrmException {
+ if (failNextUpdate.getAndSet(false)) {
+ throw new OrmException("Update failed");
+ }
+ delegate.rebuildReviewDb(db, project, changeId);
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/ChangeMessageEvent.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/ChangeMessageEvent.java
index 54303fc..ad22330 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/ChangeMessageEvent.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/ChangeMessageEvent.java
@@ -32,7 +32,7 @@
Change.Status.ABANDONED, Pattern.compile("^Abandoned(\n.*)*$"),
Change.Status.MERGED,
Pattern.compile(
- "^Change has been successfully" + " (merged|cherry-picked|rebased|pushed).*$"),
+ "^Change has been successfully (merged|cherry-picked|rebased|pushed).*$"),
Change.Status.NEW, Pattern.compile("^Restored(\n.*)*$"));
private static final Pattern TOPIC_SET_REGEXP = Pattern.compile("^Topic set to (.+)$");
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/ChangeRebuilder.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/ChangeRebuilder.java
index c8d9bb3..6f9090f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/ChangeRebuilder.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/ChangeRebuilder.java
@@ -17,6 +17,7 @@
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.notedb.ChangeBundle;
import com.google.gerrit.server.notedb.NoteDbUpdateManager;
@@ -54,6 +55,17 @@
});
}
+ /**
+ * Rebuild ReviewDb contents by copying from NoteDb.
+ *
+ * <p>Requires NoteDb to be the primary storage for the change.
+ */
+ public abstract void rebuildReviewDb(ReviewDb db, Project.NameKey project, Change.Id changeId)
+ throws OrmException;
+
+ // In the following methods "rebuilding" always refers to copying the state
+ // from ReviewDb to NoteDb, i.e. assuming ReviewDb is the primary storage.
+
public abstract Result rebuild(ReviewDb db, Change.Id changeId) throws IOException, OrmException;
public abstract Result rebuildEvenIfReadOnly(ReviewDb db, Change.Id changeId)
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/ChangeRebuilderImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/ChangeRebuilderImpl.java
index 10f4dd8..4ba3a88 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/ChangeRebuilderImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/ChangeRebuilderImpl.java
@@ -23,6 +23,7 @@
import static java.util.stream.Collectors.toList;
import com.google.common.base.Splitter;
+import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ListMultimap;
@@ -41,6 +42,7 @@
import com.google.gerrit.reviewdb.client.PatchLineComment.Status;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
+import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.reviewdb.server.ReviewDbUtil;
@@ -67,6 +69,8 @@
import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache;
+import com.google.gwtorm.client.Key;
+import com.google.gwtorm.server.Access;
import com.google.gwtorm.server.AtomicUpdate;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
@@ -74,6 +78,7 @@
import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
@@ -112,7 +117,9 @@
private final ChangeBundleReader bundleReader;
private final ChangeDraftUpdate.Factory draftUpdateFactory;
private final ChangeNoteUtil changeNoteUtil;
+ private final ChangeNotes.Factory notesFactory;
private final ChangeUpdate.Factory updateFactory;
+ private final CommentsUtil commentsUtil;
private final NoteDbUpdateManager.Factory updateManagerFactory;
private final NotesMigration migration;
private final PatchListCache patchListCache;
@@ -130,7 +137,9 @@
ChangeBundleReader bundleReader,
ChangeDraftUpdate.Factory draftUpdateFactory,
ChangeNoteUtil changeNoteUtil,
+ ChangeNotes.Factory notesFactory,
ChangeUpdate.Factory updateFactory,
+ CommentsUtil commentsUtil,
NoteDbUpdateManager.Factory updateManagerFactory,
NotesMigration migration,
PatchListCache patchListCache,
@@ -143,7 +152,9 @@
this.bundleReader = bundleReader;
this.draftUpdateFactory = draftUpdateFactory;
this.changeNoteUtil = changeNoteUtil;
+ this.notesFactory = notesFactory;
this.updateFactory = updateFactory;
+ this.commentsUtil = commentsUtil;
this.updateManagerFactory = updateManagerFactory;
this.migration = migration;
this.patchListCache = patchListCache;
@@ -613,4 +624,45 @@
update.setBranch(change.getDest().get());
update.setSubject(change.getOriginalSubject());
}
+
+ @Override
+ public void rebuildReviewDb(ReviewDb db, Project.NameKey project, Change.Id changeId)
+ throws OrmException {
+ // TODO(dborowitz): Fail fast if changes tables are disabled in ReviewDb.
+ ChangeNotes notes = notesFactory.create(db, project, changeId);
+ ChangeBundle bundle = ChangeBundle.fromNotes(commentsUtil, notes);
+
+ db = ReviewDbUtil.unwrapDb(db);
+ db.changes().beginTransaction(changeId);
+ try {
+ Change c = db.changes().get(changeId);
+ PrimaryStorage ps = PrimaryStorage.of(c);
+ if (ps != PrimaryStorage.NOTE_DB) {
+ throw new OrmException("primary storage of " + changeId + " is " + ps);
+ }
+ db.changes().upsert(Collections.singleton(c));
+ putExactlyEntities(
+ db.changeMessages(), db.changeMessages().byChange(c.getId()), bundle.getChangeMessages());
+ putExactlyEntities(db.patchSets(), db.patchSets().byChange(c.getId()), bundle.getPatchSets());
+ putExactlyEntities(
+ db.patchSetApprovals(),
+ db.patchSetApprovals().byChange(c.getId()),
+ bundle.getPatchSetApprovals());
+ putExactlyEntities(
+ db.patchComments(),
+ db.patchComments().byChange(c.getId()),
+ bundle.getPatchLineComments());
+ db.commit();
+ } finally {
+ db.rollback();
+ }
+ }
+
+ private static <T, K extends Key<?>> void putExactlyEntities(
+ Access<T, K> access, Iterable<T> existing, Collection<T> ents) throws OrmException {
+ Set<K> toKeep = access.toMap(ents).keySet();
+ access.delete(
+ FluentIterable.from(existing).filter(e -> !toKeep.contains(access.primaryKey(e))));
+ access.upsert(ents);
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java
index 9183579..957bdd7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java
@@ -194,7 +194,7 @@
if (!originalName.equals(name)) {
log.warn(
String.format(
- "Plugin provides its own name: <%s>," + " use it instead of the input name: <%s>",
+ "Plugin provides its own name: <%s>, use it instead of the input name: <%s>",
name, originalName));
}
@@ -255,8 +255,7 @@
public void disablePlugins(Set<String> names) {
if (!isRemoteAdminEnabled()) {
- log.warn(
- "Remote plugin administration is disabled," + " ignoring disablePlugins(" + names + ")");
+ log.warn("Remote plugin administration is disabled, ignoring disablePlugins(" + names + ")");
return;
}
@@ -296,8 +295,7 @@
public void enablePlugins(Set<String> names) throws PluginInstallException {
if (!isRemoteAdminEnabled()) {
- log.warn(
- "Remote plugin administration is disabled," + " ignoring enablePlugins(" + names + ")");
+ log.warn("Remote plugin administration is disabled, ignoring enablePlugins(" + names + ")");
return;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/CheckMergeability.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/CheckMergeability.java
index b704fc8..f824f81 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/CheckMergeability.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/CheckMergeability.java
@@ -61,7 +61,7 @@
@Option(
name = "--strategy",
metaVar = "STRATEGY",
- usage = "name of the merge strategy, refer to " + "org.eclipse.jgit.merge.MergeStrategy"
+ usage = "name of the merge strategy, refer to org.eclipse.jgit.merge.MergeStrategy"
)
public void setStrategy(String strategy) {
this.strategy = strategy;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/SetAccess.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/SetAccess.java
index b36a09d..c74efc6 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/SetAccess.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/SetAccess.java
@@ -107,7 +107,7 @@
checkGlobalCapabilityPermissions(config.getName());
} else if (!projectControl.controlForRef(section.getName()).isOwner()) {
throw new AuthException(
- "You are not allowed to edit permissions" + "for ref: " + section.getName());
+ "You are not allowed to edit permissionsfor ref: " + section.getName());
}
}
// Perform addition checks
@@ -122,7 +122,7 @@
throw new BadRequestException("invalid section name");
}
if (!projectControl.controlForRef(name).isOwner()) {
- throw new AuthException("You are not allowed to edit permissions" + "for ref: " + name);
+ throw new AuthException("You are not allowed to edit permissionsfor ref: " + name);
}
RefPattern.validate(name);
}
@@ -273,12 +273,12 @@
if (!allProjects.equals(projectName)) {
throw new BadRequestException(
- "Cannot edit global capabilities " + "for projects other than " + allProjects.get());
+ "Cannot edit global capabilities for projects other than " + allProjects.get());
}
if (!identifiedUser.get().getCapabilities().canAdministrateServer()) {
throw new AuthException(
- "Editing global capabilities " + "requires " + GlobalCapability.ADMINISTRATE_SERVER);
+ "Editing global capabilities requires " + GlobalCapability.ADMINISTRATE_SERVER);
}
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/SubmitRuleEvaluator.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/SubmitRuleEvaluator.java
index e6ad352..d535062 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/SubmitRuleEvaluator.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/SubmitRuleEvaluator.java
@@ -246,7 +246,7 @@
// whether or not that is actually possible given the permissions.
return ruleError(
String.format(
- "Submit rule '%s' for change %s of %s has " + "no solution.",
+ "Submit rule '%s' for change %s of %s has no solution.",
getSubmitRuleName(), cd.getId(), getProjectName()));
}
@@ -362,7 +362,7 @@
private List<SubmitRecord> invalidResult(Term rule, Term record, String reason) {
return ruleError(
String.format(
- "Submit rule %s for change %s of %s output " + "invalid result: %s%s",
+ "Submit rule %s for change %s of %s output invalid result: %s%s",
rule,
cd.getId(),
getProjectName(),
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/AndPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/AndPredicate.java
index 7e03355..1bf6d8b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/AndPredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/AndPredicate.java
@@ -86,7 +86,7 @@
for (Predicate<T> c : children) {
checkState(
c.isMatchable(),
- "match invoked, but child predicate %s " + "doesn't implement %s",
+ "match invoked, but child predicate %s doesn't implement %s",
c,
Matchable.class.getName());
if (!c.asMatchable().match(object)) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/NotPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/NotPredicate.java
index 530dfb9..3716ec1 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/NotPredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/NotPredicate.java
@@ -67,7 +67,7 @@
public boolean match(final T object) throws OrmException {
checkState(
that.isMatchable(),
- "match invoked, but child predicate %s " + "doesn't implement %s",
+ "match invoked, but child predicate %s doesn't implement %s",
that,
Matchable.class.getName());
return !that.asMatchable().match(object);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/OrPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/OrPredicate.java
index 1dd46f9..4845a86 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/OrPredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/OrPredicate.java
@@ -86,7 +86,7 @@
for (final Predicate<T> c : children) {
checkState(
c.isMatchable(),
- "match invoked, but child predicate %s " + "doesn't implement %s",
+ "match invoked, but child predicate %s doesn't implement %s",
c,
Matchable.class.getName());
if (c.asMatchable().match(object)) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/QueryProcessor.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/QueryProcessor.java
index b5ea361..5fb4497 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/QueryProcessor.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/QueryProcessor.java
@@ -52,8 +52,7 @@
executionTime =
metricMaker.newTimer(
"query/query_latency",
- new Description(
- "Successful query latency," + " accumulated over the life of the process")
+ new Description("Successful query latency, accumulated over the life of the process")
.setCumulative()
.setUnit(Description.Units.MILLISECONDS),
index);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java
index 84af7be..787508a7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java
@@ -668,7 +668,7 @@
if (project == null) {
checkState(
!notesMigration.readChanges(),
- "should not have created " + " ChangeData without a project when NoteDb is enabled");
+ "should not have created ChangeData without a project when NoteDb is enabled");
project = change().getProject();
}
return project;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_106.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_106.java
index 294c96d..5bb3669 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_106.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_106.java
@@ -151,7 +151,7 @@
} catch (IOException e) {
throw new IOException(
String.format(
- "ERROR: Failed to create reflog file for the" + " %s branch in repository %s",
+ "ERROR: Failed to create reflog file for the %s branch in repository %s",
RefNames.REFS_CONFIG, project.get()));
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_123.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_123.java
index 5a0c61d..ec63141 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_123.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_123.java
@@ -56,8 +56,7 @@
ListMultimap<Account.Id, Change.Id> imports =
MultimapBuilder.hashKeys().arrayListValues().build();
try (Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
- ResultSet rs =
- stmt.executeQuery("SELECT " + "account_id, " + "change_id " + "FROM starred_changes")) {
+ ResultSet rs = stmt.executeQuery("SELECT account_id, change_id FROM starred_changes")) {
while (rs.next()) {
Account.Id accountId = new Account.Id(rs.getInt(1));
Change.Id changeId = new Change.Id(rs.getInt(2));
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_94.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_94.java
index 5a87562..d4a189f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_94.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_94.java
@@ -29,7 +29,7 @@
@Override
protected void migrateData(ReviewDb db, UpdateUI ui) throws SQLException {
try (Statement stmt = newStatement(db)) {
- stmt.execute("CREATE INDEX patch_sets_byRevision" + " ON patch_sets (revision)");
+ stmt.execute("CREATE INDEX patch_sets_byRevision ON patch_sets (revision)");
}
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_98.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_98.java
index 4206dce..eec3c9f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_98.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_98.java
@@ -28,7 +28,7 @@
@Override
protected void migrateData(ReviewDb db, UpdateUI ui) throws SQLException {
- ui.message("Migrate user preference showUserInReview to " + "reviewCategoryStrategy");
+ ui.message("Migrate user preference showUserInReview to reviewCategoryStrategy");
try (Statement stmt = newStatement(db)) {
stmt.executeUpdate(
"UPDATE accounts SET "
diff --git a/gerrit-server/src/test/java/com/google/gerrit/rules/GerritCommonTest.java b/gerrit-server/src/test/java/com/google/gerrit/rules/GerritCommonTest.java
index 28f10d9..fa4a951 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/rules/GerritCommonTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/rules/GerritCommonTest.java
@@ -71,7 +71,7 @@
PrologEnvironment env = envFactory.create(machine);
setUpEnvironment(env);
- String script = "loopy :- b(5).\n" + "b(N) :- N > 0, !, S = N - 1, b(S).\n" + "b(_) :- true.\n";
+ String script = "loopy :- b(5).\nb(N) :- N > 0, !, S = N - 1, b(S).\nb(_) :- true.\n";
SymbolTerm nameTerm = SymbolTerm.create("testReductionLimit");
JavaObjectTerm inTerm =
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/change/HashtagsTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/change/HashtagsTest.java
index 96bac3c..780ac71 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/change/HashtagsTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/change/HashtagsTest.java
@@ -87,7 +87,7 @@
@Test
public void hashtagsWithAccentedCharacters() throws Exception {
- String commitMessage = "Jag #måste #öva på min #Svenska!\n\n" + "Jag behöver en #läkare.";
+ String commitMessage = "Jag #måste #öva på min #Svenska!\n\nJag behöver en #läkare.";
assertThat(HashtagsUtil.extractTags(commitMessage))
.containsExactlyElementsIn(Sets.newHashSet("måste", "öva", "Svenska", "läkare"));
}
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java
index d4577c5..ab68c10 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java
@@ -199,7 +199,7 @@
ProjectConfig cfg = read(rev);
assertThat(cfg.getValidationErrors()).hasSize(1);
assertThat(Iterables.getOnlyElement(cfg.getValidationErrors()).getMessage())
- .isEqualTo("project.config: Invalid defaultValue \"-2\" " + "for label \"CustomLabel\"");
+ .isEqualTo("project.config: Invalid defaultValue \"-2\" for label \"CustomLabel\"");
}
@Test
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/MetadataParserTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/MetadataParserTest.java
index 76995d5..0c4507e 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/MetadataParserTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/MetadataParserTest.java
@@ -62,11 +62,11 @@
b.subject("");
StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append(toFooterWithDelimiter(MetadataName.CHANGE_ID) + "cid" + "\r\n");
- stringBuilder.append("> " + toFooterWithDelimiter(MetadataName.PATCH_SET) + "1" + "\n");
- stringBuilder.append(toFooterWithDelimiter(MetadataName.MESSAGE_TYPE) + "comment" + "\n");
+ stringBuilder.append(toFooterWithDelimiter(MetadataName.CHANGE_ID) + "cid\r\n");
+ stringBuilder.append("> " + toFooterWithDelimiter(MetadataName.PATCH_SET) + "1\n");
+ stringBuilder.append(toFooterWithDelimiter(MetadataName.MESSAGE_TYPE) + "comment\n");
stringBuilder.append(
- toFooterWithDelimiter(MetadataName.TIMESTAMP) + "Tue, 25 Oct 2016 02:11:35 -0700" + "\r\n");
+ toFooterWithDelimiter(MetadataName.TIMESTAMP) + "Tue, 25 Oct 2016 02:11:35 -0700\r\n");
b.textContent(stringBuilder.toString());
Address author = new Address("Diffy", "test@gerritcodereview.com");
@@ -92,10 +92,10 @@
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(
- "<div id\"someid\">" + toFooterWithDelimiter(MetadataName.CHANGE_ID) + "cid" + "</div>");
- stringBuilder.append("<div>" + toFooterWithDelimiter(MetadataName.PATCH_SET) + "1" + "</div>");
+ "<div id\"someid\">" + toFooterWithDelimiter(MetadataName.CHANGE_ID) + "cid</div>");
+ stringBuilder.append("<div>" + toFooterWithDelimiter(MetadataName.PATCH_SET) + "1</div>");
stringBuilder.append(
- "<div>" + toFooterWithDelimiter(MetadataName.MESSAGE_TYPE) + "comment" + "</div>");
+ "<div>" + toFooterWithDelimiter(MetadataName.MESSAGE_TYPE) + "comment</div>");
stringBuilder.append(
"<div>"
+ toFooterWithDelimiter(MetadataName.TIMESTAMP)
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/data/AttachmentMessage.java b/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/data/AttachmentMessage.java
index 2c418ec..d8530b5 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/data/AttachmentMessage.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/data/AttachmentMessage.java
@@ -72,7 +72,7 @@
System.out.println("\uD83D\uDE1B test");
MailMessage.Builder expect = MailMessage.builder();
expect
- .id("<CAM7sg=3meaAVUxW3KXeJEVs8sv_ADw1BnvpcHHiYVR2TQQi__w" + "@mail.gmail.com>")
+ .id("<CAM7sg=3meaAVUxW3KXeJEVs8sv_ADw1BnvpcHHiYVR2TQQi__w@mail.gmail.com>")
.from(new Address("Patrick Hiesel", "hiesel@google.com"))
.addTo(new Address("Patrick Hiesel", "hiesel@google.com"))
.textContent("Contains unwanted attachment")
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/data/HtmlMimeMessage.java b/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/data/HtmlMimeMessage.java
index c19e618..487e9dd 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/data/HtmlMimeMessage.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/data/HtmlMimeMessage.java
@@ -96,7 +96,7 @@
.addTo(new Address("Patrick Hiesel", "hiesel@google.com"))
.textContent(textContent)
.htmlContent(unencodedHtmlContent)
- .subject("Change in gerrit[master]: Implement " + "receiver class structure and bindings")
+ .subject("Change in gerrit[master]: Implement receiver class structure and bindings")
.addAdditionalHeader("MIME-Version: 1.0")
.dateReceived(new DateTime(2016, 10, 25, 9, 11, 35, 0, DateTimeZone.UTC));
return expect.build();
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/data/SimpleTextMessage.java b/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/data/SimpleTextMessage.java
index 8fc1dbc..ce833d5 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/data/SimpleTextMessage.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/data/SimpleTextMessage.java
@@ -123,10 +123,10 @@
.addCc(new Address("Jonathan Nieder", "jrn@google.com"))
.addCc(new Address("Patrick Hiesel", "hiesel@google.com"))
.textContent(textContent)
- .subject("Change in gerrit[master]: (Re)enable voting" + " buttons for merged changes")
+ .subject("Change in gerrit[master]: (Re)enable voting buttons for merged changes")
.dateReceived(new DateTime(2016, 10, 25, 9, 11, 35, 0, DateTimeZone.UTC))
.addAdditionalHeader(
- "Authentication-Results: mx.google.com; " + "dkim=pass header.i=@google.com;")
+ "Authentication-Results: mx.google.com; dkim=pass header.i=@google.com;")
.addAdditionalHeader(
"In-Reply-To: <gerrit.1477487889000.Iba501e00bee"
+ "77be3bd0ced72f88fd04ba0accaed@gerrit-review.googlesource.com>")
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeBundleTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeBundleTest.java
index 916ba9f..90e6800 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeBundleTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeBundleTest.java
@@ -121,7 +121,7 @@
b1,
b2,
"changeId differs for Changes: {" + id1 + "} != {" + id2 + "}",
- "createdOn differs for Changes:" + " {2009-09-30 17:00:00.0} != {2009-09-30 17:00:06.0}",
+ "createdOn differs for Changes: {2009-09-30 17:00:00.0} != {2009-09-30 17:00:06.0}",
"effective last updated time differs for Changes:"
+ " {2009-09-30 17:00:00.0} != {2009-09-30 17:00:06.0}");
}
@@ -310,7 +310,7 @@
ChangeBundle b2 =
new ChangeBundle(
c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ":" + " {} != {null}");
+ assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ": {} != {null}");
// Topic ignored if ReviewDb is empty and NoteDb is null.
b1 =
@@ -328,7 +328,7 @@
b2 =
new ChangeBundle(
c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ":" + " {} != {null}");
+ assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ": {} != {null}");
// Null is not equal to a non-empty string.
Change c3 = clone(c1);
@@ -339,7 +339,7 @@
b2 =
new ChangeBundle(
c2, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ":" + " {topic} != {null}");
+ assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ": {topic} != {null}");
// Null is equal to a string that is all whitespace.
Change c4 = clone(c1);
@@ -368,7 +368,7 @@
ChangeBundle b2 =
new ChangeBundle(
c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ":" + " { abc } != {abc}");
+ assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ": { abc } != {abc}");
// Leading whitespace in ReviewDb topic is ignored.
b1 =
@@ -389,7 +389,7 @@
b2 =
new ChangeBundle(
c3, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ":" + " { abc } != {cba}");
+ assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ": { abc } != {cba}");
}
@Test
@@ -492,7 +492,7 @@
assertDiffs(
b1,
b2,
- "subject differs for Change.Id " + c1.getId() + ":" + " {Change subject} != {Change sub}");
+ "subject differs for Change.Id " + c1.getId() + ": {Change subject} != {Change sub}");
// ReviewDb has shorter subject, allowed.
b1 =
@@ -512,7 +512,7 @@
assertDiffs(
b1,
b2,
- "subject differs for Change.Id " + c1.getId() + ":" + " {Change subject} != {Change sub}");
+ "subject differs for Change.Id " + c1.getId() + ": {Change subject} != {Change sub}");
}
@Test
@@ -645,7 +645,7 @@
assertDiffs(
b1,
b2,
- "currentPatchSetId differs for Change.Id " + c1.getId() + ":" + " {1} != {0}",
+ "currentPatchSetId differs for Change.Id " + c1.getId() + ": {1} != {0}",
"subject differs for Change.Id "
+ c1.getId()
+ ":"
@@ -807,10 +807,8 @@
b2 =
new ChangeBundle(
c, messages(cm1), latest(c), approvals(), comments(), reviewers(), NOTE_DB);
- assertDiffs(
- b1, b2, "ChangeMessages differ for Change.Id " + id + "\n" + "Only in A:\n " + cm2);
- assertDiffs(
- b2, b1, "ChangeMessages differ for Change.Id " + id + "\n" + "Only in B:\n " + cm2);
+ assertDiffs(b1, b2, "ChangeMessages differ for Change.Id " + id + "\nOnly in A:\n " + cm2);
+ assertDiffs(b2, b1, "ChangeMessages differ for Change.Id " + id + "\nOnly in B:\n " + cm2);
}
@Test
@@ -1028,8 +1026,7 @@
new ChangeBundle(
c, messages(), patchSets(ps1, ps2), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1, b2, "PatchSet.Id sets differ:" + " [] only in A; [" + c.getId() + ",1] only in B");
+ assertDiffs(b1, b2, "PatchSet.Id sets differ: [] only in A; [" + c.getId() + ",1] only in B");
}
@Test
@@ -1200,8 +1197,8 @@
b1,
b2,
"ChangeMessage.Key sets differ: [] only in A; [" + cm2.getKey() + "] only in B",
- "PatchSet.Id sets differ:" + " [] only in A; [" + ps2.getId() + "] only in B",
- "PatchSetApproval.Key sets differ:" + " [] only in A; [" + a2.getKey() + "] only in B");
+ "PatchSet.Id sets differ: [] only in A; [" + ps2.getId() + "] only in B",
+ "PatchSetApproval.Key sets differ: [] only in A; [" + a2.getKey() + "] only in B");
// One NoteDb.
b1 =
@@ -1219,9 +1216,9 @@
assertDiffs(
b1,
b2,
- "ChangeMessages differ for Change.Id " + c.getId() + "\n" + "Only in B:\n " + cm2,
- "PatchSet.Id sets differ:" + " [] only in A; [" + ps2.getId() + "] only in B",
- "PatchSetApproval.Key sets differ:" + " [] only in A; [" + a2.getKey() + "] only in B");
+ "ChangeMessages differ for Change.Id " + c.getId() + "\nOnly in B:\n " + cm2,
+ "PatchSet.Id sets differ: [] only in A; [" + ps2.getId() + "] only in B",
+ "PatchSetApproval.Key sets differ: [] only in A; [" + a2.getKey() + "] only in B");
// Both NoteDb.
b1 =
@@ -1239,9 +1236,9 @@
assertDiffs(
b1,
b2,
- "ChangeMessages differ for Change.Id " + c.getId() + "\n" + "Only in B:\n " + cm2,
- "PatchSet.Id sets differ:" + " [] only in A; [" + ps2.getId() + "] only in B",
- "PatchSetApproval.Key sets differ:" + " [] only in A; [" + a2.getKey() + "] only in B");
+ "ChangeMessages differ for Change.Id " + c.getId() + "\nOnly in B:\n " + cm2,
+ "PatchSet.Id sets differ: [] only in A; [" + ps2.getId() + "] only in B",
+ "PatchSetApproval.Key sets differ: [] only in A; [" + a2.getKey() + "] only in B");
}
@Test
@@ -1265,7 +1262,7 @@
new ChangeBundle(
c, messages(), patchSets(ps2), approvals(), comments(), reviewers(), REVIEW_DB);
assertDiffs(
- b1, b2, "description differs for PatchSet.Id " + ps1.getId() + ":" + " { abc } != {abc}");
+ b1, b2, "description differs for PatchSet.Id " + ps1.getId() + ": { abc } != {abc}");
// Whitespace in ReviewDb description is ignored.
b1 =
@@ -1287,7 +1284,7 @@
new ChangeBundle(
c, messages(), patchSets(ps3), approvals(), comments(), reviewers(), NOTE_DB);
assertDiffs(
- b1, b2, "description differs for PatchSet.Id " + ps1.getId() + ":" + " { abc } != {cba}");
+ b1, b2, "description differs for PatchSet.Id " + ps1.getId() + ": { abc } != {cba}");
}
@Test
@@ -1617,7 +1614,7 @@
new ChangeBundle(c, messages(), latest(c), approvals(), comments(), r2, REVIEW_DB);
assertNoDiffs(b1, b1);
assertNoDiffs(b2, b2);
- assertDiffs(b1, b2, "reviewer sets differ:" + " [1] only in A;" + " [2] only in B");
+ assertDiffs(b1, b2, "reviewer sets differ: [1] only in A; [2] only in B");
}
@Test
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesParserTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesParserTest.java
index abc87d4..39c4c08 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesParserTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesParserTest.java
@@ -57,7 +57,7 @@
+ "Subject: This is a test change\n");
assertParseFails(
writeCommit(
- "Update change\n" + "\n" + "Patch-set: 1\n",
+ "Update change\n\nPatch-set: 1\n",
new PersonIdent(
"Change Owner",
"owner@example.com",
@@ -65,12 +65,12 @@
serverIdent.getTimeZone())));
assertParseFails(
writeCommit(
- "Update change\n" + "\n" + "Patch-set: 1\n",
+ "Update change\n\nPatch-set: 1\n",
new PersonIdent(
"Change Owner", "x@gerrit", serverIdent.getWhen(), serverIdent.getTimeZone())));
assertParseFails(
writeCommit(
- "Update change\n" + "\n" + "Patch-set: 1\n",
+ "Update change\n\nPatch-set: 1\n",
new PersonIdent(
"Change\n\u1234<Owner>",
"\n\nx<@>\u0002gerrit",
@@ -96,9 +96,8 @@
+ "Patch-set: 1\n"
+ "Status: new\n"
+ "Subject: This is a test change\n");
- assertParseFails("Update change\n" + "\n" + "Patch-set: 1\n" + "Status: OOPS\n");
- assertParseFails(
- "Update change\n" + "\n" + "Patch-set: 1\n" + "Status: NEW\n" + "Status: NEW\n");
+ assertParseFails("Update change\n\nPatch-set: 1\nStatus: OOPS\n");
+ assertParseFails("Update change\n\nPatch-set: 1\nStatus: NEW\nStatus: NEW\n");
}
@Test
@@ -110,8 +109,8 @@
+ "Change-id: I577fb248e474018276351785930358ec0450e9f7\n"
+ "Patch-set: 1\n"
+ "Subject: This is a test change\n");
- assertParseFails("Update change\n" + "\n");
- assertParseFails("Update change\n" + "\n" + "Patch-set: 1\n" + "Patch-set: 1\n");
+ assertParseFails("Update change\n\n");
+ assertParseFails("Update change\n\nPatch-set: 1\nPatch-set: 1\n");
assertParseSucceeds(
"Update change\n"
+ "\n"
@@ -119,7 +118,7 @@
+ "Change-id: I577fb248e474018276351785930358ec0450e9f7\n"
+ "Patch-set: 1\n"
+ "Subject: This is a test change\n");
- assertParseFails("Update change\n" + "\n" + "Patch-set: x\n");
+ assertParseFails("Update change\n\nPatch-set: x\n");
}
@Test
@@ -144,14 +143,12 @@
+ "Label: -Label1\n"
+ "Label: -Label1 Other Account <2@gerrit>\n"
+ "Subject: This is a test change\n");
- assertParseFails("Update change\n" + "\n" + "Patch-set: 1\n" + "Label: Label1=X\n");
- assertParseFails("Update change\n" + "\n" + "Patch-set: 1\n" + "Label: Label1 = 1\n");
- assertParseFails("Update change\n" + "\n" + "Patch-set: 1\n" + "Label: X+Y\n");
- assertParseFails(
- "Update change\n" + "\n" + "Patch-set: 1\n" + "Label: Label1 Other Account <2@gerrit>\n");
- assertParseFails("Update change\n" + "\n" + "Patch-set: 1\n" + "Label: -Label!1\n");
- assertParseFails(
- "Update change\n" + "\n" + "Patch-set: 1\n" + "Label: -Label!1 Other Account <2@gerrit>\n");
+ assertParseFails("Update change\n\nPatch-set: 1\nLabel: Label1=X\n");
+ assertParseFails("Update change\n\nPatch-set: 1\nLabel: Label1 = 1\n");
+ assertParseFails("Update change\n\nPatch-set: 1\nLabel: X+Y\n");
+ assertParseFails("Update change\n\nPatch-set: 1\nLabel: Label1 Other Account <2@gerrit>\n");
+ assertParseFails("Update change\n\nPatch-set: 1\nLabel: -Label!1\n");
+ assertParseFails("Update change\n\nPatch-set: 1\nLabel: -Label!1 Other Account <2@gerrit>\n");
}
@Test
@@ -169,8 +166,8 @@
+ "Submitted-with: NOT_READY\n"
+ "Submitted-with: OK: Verified: Change Owner <1@gerrit>\n"
+ "Submitted-with: NEED: Alternative-Code-Review\n");
- assertParseFails("Update change\n" + "\n" + "Patch-set: 1\n" + "Submitted-with: OOPS\n");
- assertParseFails("Update change\n" + "\n" + "Patch-set: 1\n" + "Submitted-with: NEED: X+Y\n");
+ assertParseFails("Update change\n\nPatch-set: 1\nSubmitted-with: OOPS\n");
+ assertParseFails("Update change\n\nPatch-set: 1\nSubmitted-with: NEED: X+Y\n");
assertParseFails(
"Update change\n"
+ "\n"
@@ -212,7 +209,7 @@
+ "Reviewer: Change Owner <1@gerrit>\n"
+ "CC: Other Account <2@gerrit>\n"
+ "Subject: This is a test change\n");
- assertParseFails("Update change\n" + "\n" + "Patch-set: 1\n" + "Reviewer: 1@gerrit\n");
+ assertParseFails("Update change\n\nPatch-set: 1\nReviewer: 1@gerrit\n");
}
@Test
@@ -233,8 +230,7 @@
+ "Patch-set: 1\n"
+ "Topic:\n"
+ "Subject: This is a test change\n");
- assertParseFails(
- "Update change\n" + "\n" + "Patch-set: 1\n" + "Topic: Some Topic\n" + "Topic: Other Topic");
+ assertParseFails("Update change\n\nPatch-set: 1\nTopic: Some Topic\nTopic: Other Topic");
}
@Test
@@ -453,10 +449,10 @@
@Test
public void currentPatchSet() throws Exception {
- assertParseSucceeds("Update change\n" + "\n" + "Patch-set: 1\n" + "Current: true");
- assertParseSucceeds("Update change\n" + "\n" + "Patch-set: 1\n" + "Current: tRUe");
- assertParseFails("Update change\n" + "\n" + "Patch-set: 1\n" + "Current: false");
- assertParseFails("Update change\n" + "\n" + "Patch-set: 1\n" + "Current: blah");
+ assertParseSucceeds("Update change\n\nPatch-set: 1\nCurrent: true");
+ assertParseSucceeds("Update change\n\nPatch-set: 1\nCurrent: tRUe");
+ assertParseFails("Update change\n\nPatch-set: 1\nCurrent: false");
+ assertParseFails("Update change\n\nPatch-set: 1\nCurrent: blah");
}
private RevCommit writeCommit(String body) throws Exception {
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesTest.java
index a4990c1..9d6cb60 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesTest.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.notedb;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.reviewdb.client.RefNames.changeMetaRef;
import static com.google.gerrit.reviewdb.client.RefNames.refsDraftComments;
import static com.google.gerrit.server.notedb.ReviewerStateInternal.CC;
@@ -51,6 +52,7 @@
import com.google.gerrit.server.notedb.ChangeNotesCommit.ChangeNotesRevWalk;
import com.google.gerrit.server.util.RequestId;
import com.google.gerrit.testutil.TestChanges;
+import com.google.gerrit.testutil.TestTimeUtil;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import java.sql.Timestamp;
@@ -58,6 +60,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
@@ -1376,7 +1379,7 @@
public void changeMessageWithTrailingDoubleNewline() throws Exception {
Change c = newChange();
ChangeUpdate update = newUpdate(c, changeOwner);
- update.setChangeMessage("Testing trailing double newline\n" + "\n");
+ update.setChangeMessage("Testing trailing double newline\n\n");
update.commit();
PatchSet.Id ps1 = c.currentPatchSetId();
@@ -1385,7 +1388,7 @@
assertThat(changeMessages).hasSize(1);
ChangeMessage cm1 = Iterables.getOnlyElement(changeMessages.get(ps1));
- assertThat(cm1.getMessage()).isEqualTo("Testing trailing double newline\n" + "\n");
+ assertThat(cm1.getMessage()).isEqualTo("Testing trailing double newline\n\n");
assertThat(cm1.getAuthor()).isEqualTo(changeOwner.getAccount().getId());
}
@@ -1393,8 +1396,7 @@
public void changeMessageWithMultipleParagraphs() throws Exception {
Change c = newChange();
ChangeUpdate update = newUpdate(c, changeOwner);
- update.setChangeMessage(
- "Testing paragraph 1\n" + "\n" + "Testing paragraph 2\n" + "\n" + "Testing paragraph 3");
+ update.setChangeMessage("Testing paragraph 1\n\nTesting paragraph 2\n\nTesting paragraph 3");
update.commit();
PatchSet.Id ps1 = c.currentPatchSetId();
@@ -3193,6 +3195,76 @@
assertThat(newNotes(c).getChange().currentPatchSetId().get()).isEqualTo(2);
}
+ @Test
+ public void readOnlyUntilExpires() throws Exception {
+ Change c = newChange();
+ ChangeUpdate update = newUpdate(c, changeOwner);
+ Timestamp until = new Timestamp(TimeUtil.nowMs() + 10000);
+ update.setReadOnlyUntil(until);
+ update.commit();
+
+ update = newUpdate(c, changeOwner);
+ update.setTopic("failing-topic");
+ try {
+ update.commit();
+ assert_().fail("expected OrmException");
+ } catch (OrmException e) {
+ assertThat(e.getMessage()).contains("read-only until");
+ }
+
+ ChangeNotes notes = newNotes(c);
+ assertThat(notes.getChange().getTopic()).isNotEqualTo("failing-topic");
+ assertThat(notes.getReadOnlyUntil()).isEqualTo(until);
+
+ TestTimeUtil.incrementClock(30, TimeUnit.SECONDS);
+ update = newUpdate(c, changeOwner);
+ update.setTopic("succeeding-topic");
+ update.commit();
+
+ // Write succeeded; lease still exists, even though it's expired.
+ notes = newNotes(c);
+ assertThat(notes.getChange().getTopic()).isEqualTo("succeeding-topic");
+ assertThat(notes.getReadOnlyUntil()).isEqualTo(until);
+
+ // New lease takes precedence.
+ update = newUpdate(c, changeOwner);
+ until = new Timestamp(TimeUtil.nowMs() + 10000);
+ update.setReadOnlyUntil(until);
+ update.commit();
+ assertThat(newNotes(c).getReadOnlyUntil()).isEqualTo(until);
+ }
+
+ @Test
+ public void readOnlyUntilCleared() throws Exception {
+ Change c = newChange();
+ ChangeUpdate update = newUpdate(c, changeOwner);
+ Timestamp until = new Timestamp(TimeUtil.nowMs() + TimeUnit.DAYS.toMillis(30));
+ update.setReadOnlyUntil(until);
+ update.commit();
+
+ update = newUpdate(c, changeOwner);
+ update.setTopic("failing-topic");
+ try {
+ update.commit();
+ assert_().fail("expected OrmException");
+ } catch (OrmException e) {
+ assertThat(e.getMessage()).contains("read-only until");
+ }
+
+ // Sentinel timestamp of 0 can be written to clear lease.
+ update = newUpdate(c, changeOwner);
+ update.setReadOnlyUntil(new Timestamp(0));
+ update.commit();
+
+ update = newUpdate(c, changeOwner);
+ update.setTopic("succeeding-topic");
+ update.commit();
+
+ ChangeNotes notes = newNotes(c);
+ assertThat(notes.getChange().getTopic()).isEqualTo("succeeding-topic");
+ assertThat(notes.getReadOnlyUntil()).isEqualTo(new Timestamp(0));
+ }
+
private boolean testJson() {
return noteUtil.getWriteJson();
}
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/CommitMessageOutputTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/CommitMessageOutputTest.java
index 2e58382..25b5168 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/CommitMessageOutputTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/CommitMessageOutputTest.java
@@ -84,7 +84,7 @@
public void changeMessageCommitFormatSimple() throws Exception {
Change c = TestChanges.newChange(project, changeOwner.getAccountId(), 1);
ChangeUpdate update = newUpdate(c, changeOwner);
- update.setChangeMessage("Just a little code change.\n" + "How about a new line");
+ update.setChangeMessage("Just a little code change.\nHow about a new line");
update.commit();
assertThat(update.getRefName()).isEqualTo("refs/changes/01/1/meta");
@@ -141,8 +141,7 @@
update.commit();
assertBodyEquals(
- "Update patch set 1\n" + "\n" + "Patch-set: 1\n" + "Label: -Code-Review\n",
- update.getResult());
+ "Update patch set 1\n\nPatch-set: 1\nLabel: -Code-Review\n", update.getResult());
}
@Test
@@ -207,9 +206,7 @@
update.commit();
RevCommit commit = parseCommit(update.getResult());
- assertBodyEquals(
- "Update patch set 1\n" + "\n" + "Comment on the change.\n" + "\n" + "Patch-set: 1\n",
- commit);
+ assertBodyEquals("Update patch set 1\n\nComment on the change.\n\nPatch-set: 1\n", commit);
PersonIdent author = commit.getAuthorIdent();
assertThat(author.getName()).isEqualTo("Anonymous Coward (3)");
@@ -247,7 +244,7 @@
update.commit();
assertBodyEquals(
- "Update patch set 1\n" + "\n" + "Patch-set: 1\n" + "Reviewer: Change Owner <1@gerrit>\n",
+ "Update patch set 1\n\nPatch-set: 1\nReviewer: Change Owner <1@gerrit>\n",
update.getResult());
}
@@ -255,7 +252,7 @@
public void changeMessageWithTrailingDoubleNewline() throws Exception {
Change c = newChange();
ChangeUpdate update = newUpdate(c, changeOwner);
- update.setChangeMessage("Testing trailing double newline\n" + "\n");
+ update.setChangeMessage("Testing trailing double newline\n\n");
update.commit();
assertBodyEquals(
@@ -273,8 +270,7 @@
public void changeMessageWithMultipleParagraphs() throws Exception {
Change c = newChange();
ChangeUpdate update = newUpdate(c, changeOwner);
- update.setChangeMessage(
- "Testing paragraph 1\n" + "\n" + "Testing paragraph 2\n" + "\n" + "Testing paragraph 3");
+ update.setChangeMessage("Testing paragraph 1\n\nTesting paragraph 2\n\nTesting paragraph 3");
update.commit();
assertBodyEquals(
@@ -383,8 +379,7 @@
update.setCurrentPatchSet();
update.commit();
- assertBodyEquals(
- "Update patch set 1\n" + "\n" + "Patch-set: 1\n" + "Current: true\n", update.getResult());
+ assertBodyEquals("Update patch set 1\n\nPatch-set: 1\nCurrent: true\n", update.getResult());
}
private RevCommit parseCommit(ObjectId id) throws Exception {
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java
index cc3519d..7eda3cc 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java
@@ -21,7 +21,6 @@
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.common.data.LabelValue;
-import com.google.gerrit.lifecycle.LifecycleManager;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.ProjectConfig;
@@ -49,20 +48,13 @@
@Inject private InMemoryDatabase db;
- private LifecycleManager lifecycle;
-
@Before
public void setUp() throws Exception {
- lifecycle = new LifecycleManager();
new InMemoryModule().inject(this);
- lifecycle.start();
}
@After
public void tearDown() throws Exception {
- if (lifecycle != null) {
- lifecycle.stop();
- }
InMemoryDatabase.drop(db);
}
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/tools/hooks/CommitMsgHookTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/tools/hooks/CommitMsgHookTest.java
index ec0dad5..f53a59b 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/tools/hooks/CommitMsgHookTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/tools/hooks/CommitMsgHookTest.java
@@ -245,7 +245,7 @@
"\n"
+ //
"Change-Id: Id0b4f42d3d6fc1569595c9b97cb665e738486f5d\n", //
- call("a\n" + "\n" + "b\n"));
+ call("a\n\nb\n"));
assertEquals(
"a\n"
@@ -257,7 +257,7 @@
"\n"
+ //
"Change-Id: I7d237b20058a0f46cc3f5fabc4a0476877289d75\n", //
- call("a\n" + "\n" + "b\nc\nd\ne\n"));
+ call("a\n\nb\nc\nd\ne\n"));
assertEquals(
"a\n"
@@ -273,7 +273,7 @@
"\n"
+ //
"Change-Id: I382e662f47bf164d6878b7fe61637873ab7fa4e8\n", //
- call("a\n" + "\n" + "b\nc\nd\ne\n" + "\n" + "f\ng\nh\n"));
+ call("a\n\nb\nc\nd\ne\n\nf\ng\nh\n"));
}
@Test
@@ -286,7 +286,7 @@
"Change-Id: I7fc3876fee63c766a2063df97fbe04a2dddd8d7c\n"
+ //
SOB1, //
- call("a\n" + "\n" + SOB1));
+ call("a\n\n" + SOB1));
assertEquals(
"a\n"
@@ -298,7 +298,7 @@
SOB1
+ //
SOB2, //
- call("a\n" + "\n" + SOB1 + SOB2));
+ call("a\n\n" + SOB1 + SOB2));
}
@Test
@@ -319,7 +319,7 @@
"Change-Id: I382e662f47bf164d6878b7fe61637873ab7fa4e8\n"
+ //
SOB1, //
- call("a\n" + "\n" + "b\nc\nd\ne\n" + "\n" + "f\ng\nh\n" + "\n" + SOB1));
+ call("a\n\nb\nc\nd\ne\n\nf\ng\nh\n\n" + SOB1));
assertEquals(
"a\n"
diff --git a/gerrit-server/src/test/java/com/google/gerrit/testutil/InMemoryDatabase.java b/gerrit-server/src/test/java/com/google/gerrit/testutil/InMemoryDatabase.java
index 9a41a9c..27a0172 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/testutil/InMemoryDatabase.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/testutil/InMemoryDatabase.java
@@ -61,7 +61,7 @@
private static synchronized DataSource newDataSource() throws SQLException {
final Properties p = new Properties();
p.setProperty("driver", org.h2.Driver.class.getName());
- p.setProperty("url", "jdbc:h2:mem:" + "Test_" + (++dbCnt));
+ p.setProperty("url", "jdbc:h2:mem:Test_" + (++dbCnt));
return new SimpleDataSource(p);
}
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java
index 1c85518..8b323dc 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java
@@ -151,7 +151,7 @@
name = "--branch",
aliases = {"-b"},
metaVar = "BRANCH",
- usage = "initial branch name\n" + "(default: master)"
+ usage = "initial branch name\n(default: master)"
)
private List<String> branch;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java
index a405a8f..ca69b54 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java
@@ -141,7 +141,7 @@
@Option(
name = "--strict-labels",
- usage = "Strictly check if the labels " + "specified can be applied to the given patch set(s)"
+ usage = "Strictly check if the labels specified can be applied to the given patch set(s)"
)
private boolean strictLabels;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
index ce58921..7baaeb6 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
@@ -155,7 +155,7 @@
throw die("--active and --inactive options are mutually exclusive.");
}
if (clearHttpPassword && !Strings.isNullOrEmpty(httpPassword)) {
- throw die("--http-password and --clear-http-password options are " + "mutually exclusive.");
+ throw die("--http-password and --clear-http-password options are mutually exclusive.");
}
if (addSshKeys.contains("-") && deleteSshKeys.contains("-")) {
throw die("Only one option may use the stdin");
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetProjectCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetProjectCommand.java
index 53f76e9..0311b88 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetProjectCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetProjectCommand.java
@@ -54,7 +54,7 @@
@Option(
name = "--submit-type",
aliases = {"-t"},
- usage = "project submit type\n" + "(default: MERGE_IF_NECESSARY)"
+ usage = "project submit type\n(default: MERGE_IF_NECESSARY)"
)
private SubmitType submitType;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowQueue.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowQueue.java
index 2b8f9aa..13db697 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowQueue.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowQueue.java
@@ -90,7 +90,7 @@
"%-8s %-12s %-12s %-4s %s\n", //
"Task", "State", "StartTime", "", "Command"));
stdout.print(
- "----------------------------------------------" + "--------------------------------\n");
+ "------------------------------------------------------------------------------\n");
List<TaskInfo> tasks;
try {
@@ -163,7 +163,7 @@
}
}
stdout.print(
- "----------------------------------------------" + "--------------------------------\n");
+ "------------------------------------------------------------------------------\n");
stdout.print(" " + tasks.size() + " tasks");
if (threadPoolSize > 0) {
stdout.print(", " + threadPoolSize + " worker threads");
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/UploadArchive.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/UploadArchive.java
index 1ce3dc9..4b8771a 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/UploadArchive.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/UploadArchive.java
@@ -101,11 +101,7 @@
)
private boolean level9;
- @Argument(
- index = 0,
- required = true,
- usage = "The tree or commit to " + "produce an archive for."
- )
+ @Argument(index = 0, required = true, usage = "The tree or commit to produce an archive for.")
private String treeIsh = "master";
@Argument(
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/plugin/LfsPluginAuthCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/plugin/LfsPluginAuthCommand.java
index af52e3d3..0ade137 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/plugin/LfsPluginAuthCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/plugin/LfsPluginAuthCommand.java
@@ -65,7 +65,7 @@
LfsSshPluginAuth pluginAuth = auth.get();
if (pluginAuth == null) {
throw new Failure(
- 1, "Server configuration error:" + " LFS auth over SSH is not properly configured.");
+ 1, "Server configuration error: LFS auth over SSH is not properly configured.");
}
stdout.print(pluginAuth.authenticate(user.get(), args));
diff --git a/gerrit-war/src/main/java/com/google/gerrit/httpd/SitePathFromSystemConfigProvider.java b/gerrit-war/src/main/java/com/google/gerrit/httpd/SitePathFromSystemConfigProvider.java
index dee5621..0535f26 100644
--- a/gerrit-war/src/main/java/com/google/gerrit/httpd/SitePathFromSystemConfigProvider.java
+++ b/gerrit-war/src/main/java/com/google/gerrit/httpd/SitePathFromSystemConfigProvider.java
@@ -49,7 +49,7 @@
throw new OrmException("system_config table is empty");
default:
throw new OrmException(
- "system_config must have exactly 1 row;" + " found " + all.size() + " rows instead");
+ "system_config must have exactly 1 row; found " + all.size() + " rows instead");
}
}
}
diff --git a/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html b/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html
index 8ec1055..82c6afb 100644
--- a/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html
+++ b/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html
@@ -96,7 +96,7 @@
</tr>
<tr>
<td><span class="key">u</span></td>
- <td>Up to change list</td>
+ <td>Up to dashboard</td>
</tr>
</tbody>
<!-- Diff View -->
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html
index 74dc9e7..dc66bb6 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html
@@ -61,8 +61,9 @@
justify-content: flex-end;
}
gr-search-bar {
+ flex-grow: 1;
margin-left: .5em;
- width: 500px;
+ max-width: 500px;
}
.accountContainer:not(.loggedIn):not(.loggedOut) .loginButton,
.accountContainer:not(.loggedIn):not(.loggedOut) gr-account-dropdown,
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
index ebeb9af..c9abac2 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
@@ -14,6 +14,32 @@
(function() {
'use strict';
+ var ADMIN_LINKS = [
+ {
+ url: '/admin/groups',
+ name: 'Groups',
+ },
+ {
+ url: '/admin/create-group',
+ name: 'Create Group',
+ capability: 'createGroup'
+ },
+ {
+ url: '/admin/projects',
+ name: 'Projects',
+ },
+ {
+ url: '/admin/create-project',
+ name: 'Create Project',
+ capability: 'createProject',
+ },
+ {
+ url: '/admin/plugins',
+ name: 'Plugins',
+ capability: 'viewPlugins',
+ },
+ ];
+
var DEFAULT_LINKS = [{
title: 'Changes',
links: [
@@ -46,6 +72,10 @@
},
_account: Object,
+ _adminLinks: {
+ type: Array,
+ value: function() { return []; },
+ },
_defaultLinks: {
type: Array,
value: function() {
@@ -54,7 +84,7 @@
},
_links: {
type: Array,
- computed: '_computeLinks(_defaultLinks, _userLinks)',
+ computed: '_computeLinks(_defaultLinks, _userLinks, _adminLinks)',
},
_loginURL: {
type: String,
@@ -94,7 +124,7 @@
return '//' + window.location.host + path;
},
- _computeLinks: function(defaultLinks, userLinks) {
+ _computeLinks: function(defaultLinks, userLinks, adminLinks) {
var links = defaultLinks.slice();
if (userLinks && userLinks.length > 0) {
links.push({
@@ -102,6 +132,12 @@
links: userLinks,
});
}
+ if (adminLinks && adminLinks.length > 0) {
+ links.push({
+ title: 'Admin',
+ links: adminLinks,
+ });
+ }
return links;
},
@@ -120,6 +156,18 @@
this._userLinks =
prefs.my.map(this._stripHashPrefix).filter(this._isSupportedLink);
}.bind(this));
+ this._loadAccountCapabilities();
+ },
+
+ _loadAccountCapabilities: function() {
+ var params = ['createProject', 'createGroup', 'viewPlugins'];
+ return this.$.restAPI.getAccountCapabilities(params)
+ .then(function(capabilities) {
+ this._adminLinks = ADMIN_LINKS.filter(function(link) {
+ return !link.capability ||
+ capabilities.hasOwnProperty(link.capability);
+ });
+ }.bind(this));
},
_stripHashPrefix: function(linkObj) {
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html
index aef338b..75723b9 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html
@@ -33,8 +33,10 @@
<script>
suite('gr-main-header tests', function() {
var element;
+ var sandbox;
setup(function() {
+ sandbox = sinon.sandbox.create();
stub('gr-rest-api-interface', {
getConfig: function() { return Promise.resolve({}); },
});
@@ -44,6 +46,10 @@
element = fixture('basic');
});
+ teardown(function() {
+ sandbox.restore();
+ });
+
test('strip hash prefix', function() {
assert.deepEqual([
{url: '#/q/owner:self+is:draft'},
@@ -69,6 +75,30 @@
]);
});
+ test('_loadAccountCapabilities admin', function(done) {
+ sandbox.stub(element.$.restAPI, 'getAccountCapabilities', function() {
+ return Promise.resolve({
+ createGroup: true,
+ createProject: true,
+ viewPlugins: true,
+ });
+ });
+ element._loadAccountCapabilities().then(function() {
+ assert.equal(element._adminLinks.length, 5);
+ done();
+ });
+ });
+
+ test('_loadAccountCapabilities non admin', function(done) {
+ sandbox.stub(element.$.restAPI, 'getAccountCapabilities', function() {
+ return Promise.resolve({});
+ });
+ element._loadAccountCapabilities().then(function() {
+ assert.equal(element._adminLinks.length, 2);
+ done();
+ });
+ });
+
test('user links', function() {
var defaultLinks = [{
title: 'Faves',
@@ -81,11 +111,21 @@
name: 'Facebook',
url: 'https://facebook.com',
}];
- assert.deepEqual(element._computeLinks(defaultLinks, []), defaultLinks);
- assert.deepEqual(element._computeLinks(defaultLinks, userLinks),
+ var adminLinks = [{
+ url: '/admin/groups',
+ name: 'Groups',
+ }];
+
+ assert.deepEqual(
+ element._computeLinks(defaultLinks, [], []), defaultLinks);
+ assert.deepEqual(
+ element._computeLinks(defaultLinks, userLinks, adminLinks),
defaultLinks.concat({
title: 'Your',
links: userLinks,
+ }, {
+ title: 'Admin',
+ links: adminLinks,
}));
});
});
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread.js b/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread.js
index c088b1a..81c2752 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread.js
@@ -225,7 +225,7 @@
_handleCommentAck: function(e) {
var comment = this._lastComment;
- this._createReplyComment(comment, 'Ack', false, comment.unresolved);
+ this._createReplyComment(comment, 'Ack', false, false);
},
_handleCommentDone: function(e) {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread_test.html b/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread_test.html
index e0ae9ff..da61e41 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread_test.html
@@ -278,6 +278,7 @@
assert.equal(drafts.length, 1);
assert.equal(drafts[0].message, 'Ack');
assert.equal(drafts[0].in_reply_to, 'baf0414d_60047215');
+ assert.equal(drafts[0].unresolved, false);
done();
});
});
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.js b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.js
index 10f04c6..c354882a 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.js
@@ -24,6 +24,8 @@
RIGHT: 'selected-right',
};
+ var getNewCache = function() { return {left: null, right: null}; };
+
Polymer({
is: 'gr-diff-selection',
@@ -32,10 +34,14 @@
_cachedDiffBuilder: Object,
_linesCache: {
type: Object,
- value: function() { return {left: null, right: null}; },
+ value: getNewCache(),
},
},
+ observers: [
+ '_diffChanged(diff)',
+ ],
+
listeners: {
'copy': '_handleCopy',
'down': '_handleDown',
@@ -53,6 +59,10 @@
return this._cachedDiffBuilder;
},
+ _diffChanged: function() {
+ this._linesCache = getNewCache();
+ },
+
_handleDown: function(e) {
var lineEl = this.diffBuilder.getLineElByChild(e.target);
if (!lineEl) {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection_test.html b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection_test.html
index d517a80..86edf6b 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection_test.html
@@ -325,5 +325,12 @@
'is is a co');
});
});
+
+ test('cache is reset when diff changes', function() {
+ element._linesCache = {left: 'test', right: 'test'};
+ element.diff = {};
+ flushAsynchronousOperations();
+ assert.deepEqual(element._linesCache, {left: null, right: null});
+ });
});
</script>
diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.js b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.js
index 61c3a44..0ce3aba 100644
--- a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.js
+++ b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.js
@@ -64,7 +64,6 @@
'gr-diff gr-syntax gr-syntax-string': true,
'gr-diff gr-syntax gr-syntax-selector-id': true,
'gr-diff gr-syntax gr-syntax-title': true,
- 'gr-diff gr-syntax gr-syntax-params': true,
'gr-diff gr-syntax gr-syntax-comment': true,
'gr-diff gr-syntax gr-syntax-meta': true,
'gr-diff gr-syntax gr-syntax-meta-keyword': true,
diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-themes/gr-theme-default.html b/polygerrit-ui/app/elements/diff/gr-syntax-themes/gr-theme-default.html
index 633e24a..fabc347 100644
--- a/polygerrit-ui/app/elements/diff/gr-syntax-themes/gr-theme-default.html
+++ b/polygerrit-ui/app/elements/diff/gr-syntax-themes/gr-theme-default.html
@@ -60,7 +60,6 @@
.gr-syntax-meta-keyword {
color: #219;
}
- .gr-syntax-params,
.gr-syntax-type {
color: #00f;
}
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
index 5c2ad5c..b9b1f53 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
@@ -317,6 +317,17 @@
return this._fetchSharedCacheURL('/accounts/self/groups');
},
+ getAccountCapabilities: function(opt_params) {
+ var queryString = '';
+ if (opt_params) {
+ queryString = '?q=' + opt_params
+ .map(function(param) { return encodeURIComponent(param); })
+ .join('&q=');
+ }
+ return this._fetchSharedCacheURL('/accounts/self/capabilities' +
+ queryString);
+ },
+
getLoggedIn: function() {
return this.getAccount().then(function(account) {
return account != null;