Merge branch stable-2.12
* stable-2.12:
Adapt to the JGit v4.5.x
Change-Id: I45ca07a7bc98d3d8acb2d8af0516a42eef90e845
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 72c9ec9..249700a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java
@@ -17,12 +17,10 @@
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelTypes;
-import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change;
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.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.GerritPersonIdent;
@@ -31,12 +29,16 @@
import com.google.gerrit.server.config.AnonymousCowardName;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.git.NotesBranchUtil;
+import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
+import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
@@ -78,8 +80,10 @@
private final LabelTypes labelTypes;
private final ApprovalsUtil approvalsUtil;
private final ChangeControl.GenericFactory changeControlFactory;
+ private final ChangeNotes.Factory notesFactory;
private final IdentifiedUser.GenericFactory userFactory;
private final NotesBranchUtil.Factory notesBranchUtilFactory;
+ private final Provider<InternalChangeQuery> queryProvider;
private final String canonicalWebUrl;
private final ReviewDb reviewDb;
private final Project.NameKey project;
@@ -90,18 +94,20 @@
private StringBuilder message;
@Inject
- CreateReviewNotes(@GerritPersonIdent final PersonIdent gerritIdent,
- final AccountCache accountCache,
- @AnonymousCowardName final String anonymousCowardName,
- final ProjectCache projectCache,
- final ApprovalsUtil approvalsUtil,
- final ChangeControl.GenericFactory changeControlFactory,
- final IdentifiedUser.GenericFactory userFactory,
- final NotesBranchUtil.Factory notesBranchUtilFactory,
- @Nullable @CanonicalWebUrl final String canonicalWebUrl,
- @Assisted final ReviewDb reviewDb,
- @Assisted final Project.NameKey project,
- @Assisted final Repository git) {
+ CreateReviewNotes(@GerritPersonIdent PersonIdent gerritIdent,
+ AccountCache accountCache,
+ @AnonymousCowardName String anonymousCowardName,
+ ProjectCache projectCache,
+ ApprovalsUtil approvalsUtil,
+ ChangeControl.GenericFactory changeControlFactory,
+ ChangeNotes.Factory notesFactory,
+ IdentifiedUser.GenericFactory userFactory,
+ NotesBranchUtil.Factory notesBranchUtilFactory,
+ Provider<InternalChangeQuery> queryProvider,
+ @Nullable @CanonicalWebUrl String canonicalWebUrl,
+ @Assisted ReviewDb reviewDb,
+ @Assisted Project.NameKey project,
+ @Assisted Repository git) {
this.gerritServerIdent = gerritIdent;
this.accountCache = accountCache;
this.anonymousCowardName = anonymousCowardName;
@@ -115,8 +121,10 @@
}
this.approvalsUtil = approvalsUtil;
this.changeControlFactory = changeControlFactory;
+ this.notesFactory = notesFactory;
this.userFactory = userFactory;
this.notesBranchUtilFactory = notesBranchUtilFactory;
+ this.queryProvider = queryProvider;
this.canonicalWebUrl = canonicalWebUrl;
this.reviewDb = reviewDb;
this.project = project;
@@ -148,29 +156,38 @@
}
for (RevCommit c : rw) {
- ObjectId content = createNoteContent(loadPatchSet(c, branch));
- if (content != null) {
- monitor.update(1);
- getNotes().set(c, content);
- getMessage().append("* ").append(c.getShortMessage()).append("\n");
+ PatchSet ps = loadPatchSet(c, branch);
+ if (ps != null) {
+ ChangeNotes notes = notesFactory.create(reviewDb, project,
+ ps.getId().getParentKey());
+ ObjectId content = createNoteContent(notes, ps);
+ if (content != null) {
+ monitor.update(1);
+ getNotes().set(c, content);
+ getMessage().append("* ").append(c.getShortMessage()).append("\n");
+ }
+ } else {
+ log.debug("no note for this commit since it is a direct push: "
+ + c.getName().substring(0, 7));
}
}
}
}
- 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");
}
}
@@ -217,13 +234,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) {
@@ -235,46 +252,34 @@
private PatchSet loadPatchSet(RevCommit c, String destBranch)
throws OrmException {
- List<PatchSet> patches = reviewDb.patchSets().byRevision(new RevId(c.name()))
- .toList();
- if (patches.isEmpty()) {
- return null; // TODO: createNoCodeReviewNote(branch, c, fmt);
- } else if (patches.size() == 1) {
- return patches.get(0);
- } else {
- Branch.NameKey dest = new Branch.NameKey(project, destBranch);
- for (PatchSet ps : patches) {
- Change.Id cid = ps.getId().getParentKey();
- Change change = reviewDb.changes().get(cid);
- if (change.getDest().equals(dest)) {
+ String hash = c.name();
+ for (ChangeData cd : queryProvider.get()
+ .byBranchCommit(project.get(), destBranch, hash)) {
+ for (PatchSet ps : cd.patchSets()) {
+ if (ps.getRevision().matches(hash)) {
return ps;
}
}
}
- return null;
+ return null; // TODO: createNoCodeReviewNote(branch, c, fmt);
}
- private void createCodeReviewNote(PatchSet ps, HeaderFormatter fmt)
- throws OrmException, NoSuchChangeException {
- createCodeReviewNote(
- reviewDb.changes().get(ps.getId().getParentKey()), ps, fmt);
- }
-
- private void createCodeReviewNote(Change change, PatchSet ps,
+ 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.
+ Change change = notes.getChange();
ChangeControl ctl = changeControlFactory.controlFor(
- change, userFactory.create(change.getOwner()));
+ notes, userFactory.create(change.getOwner()));
PatchSetApproval submit = null;
for (PatchSetApproval a :
approvalsUtil.byPatchSet(reviewDb, ctl, ps.getId())) {
if (a.getValue() == 0) {
// Ignore 0 values.
- } else if (a.isSubmit()) {
+ } else if (a.isLegacySubmit()) {
submit = a;
} else {
LabelType type = labelTypes.byLabel(a.getLabelId());
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 2b1968c..e62e1fc 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/ExportReviewNotes.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/ExportReviewNotes.java
@@ -14,10 +14,15 @@
package com.googlesource.gerrit.plugins.reviewnotes;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.MultimapBuilder;
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;
@@ -28,15 +33,11 @@
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.TextProgressMonitor;
import org.eclipse.jgit.lib.ThreadSafeProgressMonitor;
-import org.eclipse.jgit.util.BlockList;
import org.kohsuke.args4j.Option;
import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
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 +53,10 @@
@Inject
private CreateReviewNotes.Factory reviewNotesFactory;
- private Map<Project.NameKey, List<Change>> changes;
+ @Inject
+ private ChangeNotes.Factory notesFactory;
+
+ private ListMultimap<Project.NameKey, ChangeNotes> changes;
private ThreadSafeProgressMonitor monitor;
@Override
@@ -61,12 +65,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,37 +77,26 @@
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 MultimapBuilder.hashKeys().arrayListValues()
+ .build(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 Map<Project.NameKey, List<Change>> cluster(List<Change> changes) {
- HashMap<Project.NameKey, List<Change>> m = new HashMap<>();
- for (Change change : changes) {
- if (change.getStatus() == Change.Status.MERGED) {
- List<Change> l = m.get(change.getProject());
- if (l == null) {
- l = new BlockList<>();
- m.put(change.getProject(), l);
- }
- l.add(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());
@@ -114,27 +105,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.remove(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();
}
};
@@ -144,9 +135,9 @@
private class Worker extends Thread {
@Override
public void run() {
- try (ReviewDb db = database.open()){
+ 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());