ExportReviewNotes: Load changes from notedb if enabled
Make sure that change notes are created only once.
Change-Id: Ie9b936cbedc333c0d7697af706900187a34e7060
Signed-off-by: Edwin Kempin <ekempin@google.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java
index 249f9b6..9fce4c8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java
@@ -156,7 +156,10 @@
}
for (RevCommit c : rw) {
- ObjectId content = createNoteContent(loadPatchSet(c, branch));
+ PatchSet ps = loadPatchSet(c, branch);
+ ChangeNotes notes =
+ notesFactory.create(reviewDb, project, ps.getId().getParentKey());
+ ObjectId content = createNoteContent(notes, ps);
if (content != null) {
monitor.update(1);
getNotes().set(c, content);
@@ -166,19 +169,20 @@
}
}
- void createNotes(List<Change> changes, ProgressMonitor monitor)
+ void createNotes(List<ChangeNotes> notes, ProgressMonitor monitor)
throws OrmException, IOException {
try (RevWalk rw = new RevWalk(git)) {
if (monitor == null) {
monitor = NullProgressMonitor.INSTANCE;
}
- for (Change c : changes) {
+ for (ChangeNotes cn : notes) {
monitor.update(1);
- PatchSet ps = reviewDb.patchSets().get(c.currentPatchSetId());
+ PatchSet ps =
+ reviewDb.patchSets().get(cn.getChange().currentPatchSetId());
ObjectId commitId = ObjectId.fromString(ps.getRevision().get());
RevCommit commit = rw.parseCommit(commitId);
- getNotes().set(commitId, createNoteContent(ps));
+ getNotes().set(commitId, createNoteContent(cn, ps));
getMessage().append("* ").append(commit.getShortMessage()).append("\n");
}
}
@@ -225,13 +229,13 @@
}
}
- private ObjectId createNoteContent(PatchSet ps)
+ private ObjectId createNoteContent(ChangeNotes notes, PatchSet ps)
throws OrmException, IOException {
HeaderFormatter fmt =
new HeaderFormatter(gerritServerIdent.getTimeZone(), anonymousCowardName);
if (ps != null) {
try {
- createCodeReviewNote(ps, fmt);
+ createCodeReviewNote(notes, ps, fmt);
return getInserter().insert(Constants.OBJ_BLOB,
fmt.toString().getBytes("UTF-8"));
} catch (NoSuchChangeException e) {
@@ -255,15 +259,13 @@
return null; // TODO: createNoCodeReviewNote(branch, c, fmt);
}
- private void createCodeReviewNote(PatchSet ps, HeaderFormatter fmt)
- throws OrmException, NoSuchChangeException {
+ private void createCodeReviewNote(ChangeNotes notes, PatchSet ps,
+ HeaderFormatter fmt) throws OrmException, NoSuchChangeException {
// This races with the label normalization/writeback done by MergeOp. It may
// repeat some work, but results should be identical except in the case of
// an additional race with a permissions change.
// TODO(dborowitz): These will eventually be stamped in the ChangeNotes at
// commit time so we will be able to skip this normalization step.
- ChangeNotes notes =
- notesFactory.create(reviewDb, project, ps.getId().getParentKey());
Change change = notes.getChange();
ChangeControl ctl = changeControlFactory.controlFor(
notes, userFactory.create(change.getOwner()));
diff --git a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/ExportReviewNotes.java b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/ExportReviewNotes.java
index 80c5fa5..d1cbb9a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/ExportReviewNotes.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/ExportReviewNotes.java
@@ -14,12 +14,14 @@
package com.googlesource.gerrit.plugins.reviewnotes;
-import com.google.common.collect.ArrayListMultimap;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
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.git.GitRepositoryManager;
+import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.sshd.SshCommand;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
@@ -33,10 +35,8 @@
import org.kohsuke.args4j.Option;
import java.io.IOException;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
/** Export review notes for all submitted changes in all projects. */
public class ExportReviewNotes extends SshCommand {
@@ -52,7 +52,10 @@
@Inject
private CreateReviewNotes.Factory reviewNotesFactory;
- private ListMultimap<Project.NameKey, Change> changes;
+ @Inject
+ private ChangeNotes.Factory notesFactory;
+
+ private ListMultimap<Project.NameKey, ChangeNotes> changes;
private ThreadSafeProgressMonitor monitor;
@Override
@@ -61,12 +64,10 @@
threads = 1;
}
- List<Change> allChangeList = allChanges();
- monitor = new ThreadSafeProgressMonitor(new TextProgressMonitor(stdout));
- monitor.beginTask("Scanning changes", allChangeList.size());
- changes = cluster(allChangeList);
- allChangeList = null;
+ changes = mergedChanges();
+ monitor = new ThreadSafeProgressMonitor(new TextProgressMonitor(stdout));
+ monitor.beginTask("Scanning merged changes", changes.size());
monitor.startWorkers(threads);
for (int tid = 0; tid < threads; tid++) {
new Worker().start();
@@ -75,32 +76,25 @@
monitor.endTask();
}
- private List<Change> allChanges() {
- try (ReviewDb db = database.open()){
- return db.changes().all().toList();
- } catch (OrmException e) {
+ private ListMultimap<Project.NameKey, ChangeNotes> mergedChanges() {
+ try (ReviewDb db = database.open()) {
+ return notesFactory.create(db, new Predicate<ChangeNotes>() {
+ @Override
+ public boolean apply(ChangeNotes notes) {
+ return notes.getChange().getStatus() == Change.Status.MERGED;
+ }
+ });
+ } catch (OrmException | IOException e) {
stderr.println("Cannot read changes from database " + e.getMessage());
- return Collections.emptyList();
+ return ImmutableListMultimap.of();
}
}
- private ListMultimap<Project.NameKey, Change> cluster(List<Change> changes) {
- ListMultimap<Project.NameKey, Change> m = ArrayListMultimap.create();
- for (Change change : changes) {
- if (change.getStatus() == Change.Status.MERGED) {
- m.put(change.getProject(), change);
- } else {
- monitor.update(1);
- }
- }
- return m;
- }
-
- private void export(ReviewDb db, Project.NameKey project, List<Change> changes)
- throws IOException, OrmException {
+ private void export(ReviewDb db, Project.NameKey project,
+ List<ChangeNotes> notes) throws IOException, OrmException {
try (Repository git = gitManager.openRepository(project)) {
CreateReviewNotes crn = reviewNotesFactory.create(db, project, git);
- crn.createNotes(changes, monitor);
+ crn.createNotes(notes, monitor);
crn.commitNotes();
} catch (RepositoryNotFoundException e) {
stderr.println("Unable to open project: " + project.get());
@@ -109,27 +103,27 @@
}
}
- private Map.Entry<Project.NameKey, List<Change>> next() {
+ private Map.Entry<Project.NameKey, List<ChangeNotes>> next() {
synchronized (changes) {
if (changes.isEmpty()) {
return null;
}
final Project.NameKey name = changes.keySet().iterator().next();
- final List<Change> list = changes.removeAll(name);
- return new Map.Entry<Project.NameKey, List<Change>>() {
+ final List<ChangeNotes> list = changes.removeAll(name);
+ return new Map.Entry<Project.NameKey, List<ChangeNotes>>() {
@Override
public Project.NameKey getKey() {
return name;
}
@Override
- public List<Change> getValue() {
+ public List<ChangeNotes> getValue() {
return list;
}
@Override
- public List<Change> setValue(List<Change> value) {
+ public List<ChangeNotes> setValue(List<ChangeNotes> value) {
throw new UnsupportedOperationException();
}
};
@@ -141,7 +135,7 @@
public void run() {
try (ReviewDb db = database.open()){
for (;;) {
- Entry<Project.NameKey, List<Change>> next = next();
+ Map.Entry<Project.NameKey, List<ChangeNotes>> next = next();
if (next != null) {
try {
export(db, next.getKey(), next.getValue());