Extract replay revisions logic into own import step
Change-Id: I6ac0a8d1b9531d09ca4cf0181bbfed82a62583e5
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/Module.java b/src/main/java/com/googlesource/gerrit/plugins/importer/Module.java
index 4ffeabe..7ce81b1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/Module.java
@@ -45,5 +45,6 @@
bind(GitFetchStep.class);
bind(AccountUtil.class);
install(new FactoryModuleBuilder().build(ReplayChangesStep.Factory.class));
+ install(new FactoryModuleBuilder().build(ReplayRevisionsStep.Factory.class));
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
index bd7c099..df3f878 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
@@ -29,7 +29,6 @@
import com.google.gerrit.extensions.common.ChangeMessageInfo;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.LabelInfo;
-import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Account;
@@ -38,9 +37,7 @@
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
-import com.google.gerrit.reviewdb.client.PatchSetInfo;
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.ChangeMessagesUtil;
import com.google.gerrit.server.ChangeUtil;
@@ -52,7 +49,6 @@
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.notedb.ChangeUpdate;
-import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.validators.ValidationException;
@@ -62,10 +58,7 @@
import com.google.inject.assistedinject.Assisted;
import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import java.io.IOException;
@@ -90,10 +83,10 @@
Project.NameKey name);
}
+ private final ReplayRevisionsStep.Factory replayRevisionsFactory;
private final AccountUtil accountUtil;
private final ReviewDb db;
private final ChangeIndexer indexer;
- private final PatchSetInfoFactory patchSetInfoFactory;
private final Provider<PostReview> postReview;
private final ChangeUpdate.Factory updateFactory;
private final ChangeMessagesUtil cmUtil;
@@ -108,10 +101,10 @@
@Inject
ReplayChangesStep(
+ ReplayRevisionsStep.Factory replayRevisionsFactory,
AccountUtil accountUtil,
ReviewDb db,
ChangeIndexer indexer,
- PatchSetInfoFactory patchSetInfoFactory,
Provider<PostReview> postReview,
ChangeUpdate.Factory updateFactory,
ChangeMessagesUtil cmUtil,
@@ -124,10 +117,10 @@
@Assisted("password") String password,
@Assisted Repository repo,
@Assisted Project.NameKey name) {
+ this.replayRevisionsFactory = replayRevisionsFactory;
this.accountUtil = accountUtil;
this.db = db;
this.indexer = indexer;
- this.patchSetInfoFactory = patchSetInfoFactory;
this.postReview = postReview;
this.updateFactory = updateFactory;
this.cmUtil = cmUtil;
@@ -159,7 +152,7 @@
throws IOException, OrmException, NoSuchAccountException,
NoSuchChangeException, RestApiException, ValidationException {
Change change = createChange(c);
- replayRevisions(rw, change, c);
+ replayRevisionsFactory.create(repo, rw, change, c).replay();
db.changes().insert(Collections.singleton(change));
replayInlineComments(change, c);
@@ -193,57 +186,6 @@
}
}
- private void replayRevisions(RevWalk rw, Change change,
- ChangeInfo c) throws IOException, OrmException, NoSuchAccountException {
- List<RevisionInfo> revisions = new ArrayList<>(c.revisions.values());
- sortRevisionInfoByNumber(revisions);
- List<PatchSet> patchSets = new ArrayList<>();
-
- db.changes().beginTransaction(change.getId());
- try {
- for (RevisionInfo r : revisions) {
- String origRef = r.ref;
- ObjectId id = repo.resolve(origRef);
- if (id == null) {
- // already replayed?
- continue;
- }
- RevCommit commit = rw.parseCommit(id);
-
- PatchSet ps = new PatchSet(new PatchSet.Id(change.getId(), r._number));
- patchSets.add(ps);
-
- ps.setUploader(accountUtil.resolveUser(r.uploader));
- ps.setCreatedOn(r.created);
- ps.setRevision(new RevId(commit.name()));
- ps.setDraft(r.draft != null && r.draft);
-
- PatchSetInfo info = patchSetInfoFactory.get(commit, ps.getId());
- if (c.currentRevision.equals(info.getRevId())) {
- change.setCurrentPatchSet(info);
- }
-
- ChangeUtil.insertAncestors(db, ps.getId(), commit);
-
- renameRef(repo, origRef, ps);
- }
-
- db.patchSets().insert(patchSets);
- db.commit();
- } finally {
- db.rollback();
- }
- }
-
- private static void sortRevisionInfoByNumber(List<RevisionInfo> list) {
- Collections.sort(list, new Comparator<RevisionInfo>() {
- @Override
- public int compare(RevisionInfo a, RevisionInfo b) {
- return a._number - b._number;
- }
- });
- }
-
private void replayInlineComments(Change change, ChangeInfo c) throws OrmException,
RestApiException, IOException, NoSuchChangeException,
NoSuchAccountException {
@@ -308,49 +250,6 @@
input, ts);
}
- private void renameRef(Repository repo, String origRef, PatchSet ps)
- throws IOException {
- String ref = ps.getId().toRefName();
- if (ref.equals(origRef)) {
- return;
- }
-
- createRef(repo, ps);
- deleteRef(repo, ps, origRef);
- }
-
- private void createRef(Repository repo, PatchSet ps) throws IOException {
- String ref = ps.getId().toRefName();
- RefUpdate ru = repo.updateRef(ref);
- ru.setForceUpdate(true);
- ru.setExpectedOldObjectId(ObjectId.zeroId());
- ru.setNewObjectId(ObjectId.fromString(ps.getRevision().get()));
- RefUpdate.Result result = ru.update();
- switch (result) {
- case NEW:
- case FORCED:
- case FAST_FORWARD:
- return;
- default:
- throw new IOException(String.format("Failed to create ref %s", ref));
- }
- }
-
- private void deleteRef(Repository repo, PatchSet ps, String ref)
- throws IOException {
- RefUpdate ru = repo.updateRef(ref);
- ru.setForceUpdate(true);
- ru.setExpectedOldObjectId(ObjectId.fromString(ps.getRevision().get()));
- ru.setNewObjectId(ObjectId.zeroId());
- RefUpdate.Result result = ru.update();
- switch (result) {
- case FORCED:
- return;
- default:
- throw new IOException(String.format("Failed to delete ref %s", ref));
- }
- }
-
private void replayMessages(Change change, ChangeInfo c)
throws IOException, NoSuchChangeException, OrmException,
NoSuchAccountException {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
new file mode 100644
index 0000000..47eeaa5
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
@@ -0,0 +1,167 @@
+//Copyright (C) 2015 The Android Open Source Project
+//
+//Licensed under the Apache License, Version 2.0 (the "License");
+//you may not use this file except in compliance with the License.
+//You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing, software
+//distributed under the License is distributed on an "AS IS" BASIS,
+//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//See the License for the specific language governing permissions and
+//limitations under the License.
+
+package com.googlesource.gerrit.plugins.importer;
+
+import com.google.gerrit.common.errors.NoSuchAccountException;
+import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.common.RevisionInfo;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.PatchSetInfo;
+import com.google.gerrit.reviewdb.client.RevId;
+import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.ChangeUtil;
+import com.google.gerrit.server.patch.PatchSetInfoFactory;
+import com.google.gwtorm.server.OrmException;
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
+
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+class ReplayRevisionsStep {
+
+ interface Factory {
+ ReplayRevisionsStep create(Repository repo, RevWalk rw, Change change,
+ ChangeInfo changeInfo);
+ }
+
+ private final AccountUtil accountUtil;
+ private final ReviewDb db;
+ private final PatchSetInfoFactory patchSetInfoFactory;
+ private final Repository repo;
+ private final RevWalk rw;
+ private final Change change;
+ private final ChangeInfo changeInfo;
+
+ @Inject
+ public ReplayRevisionsStep(AccountUtil accountUtil,
+ ReviewDb db,
+ PatchSetInfoFactory patchSetInfoFactory,
+ @Assisted Repository repo,
+ @Assisted RevWalk rw,
+ @Assisted Change change,
+ @Assisted ChangeInfo changeInfo) {
+ this.accountUtil = accountUtil;
+ this.db = db;
+ this.patchSetInfoFactory = patchSetInfoFactory;
+ this.repo = repo;
+ this.rw = rw;
+ this.change = change;
+ this.changeInfo = changeInfo;
+ }
+
+ void replay() throws IOException, OrmException, NoSuchAccountException {
+ List<RevisionInfo> revisions = new ArrayList<>(changeInfo.revisions.values());
+ sortRevisionInfoByNumber(revisions);
+ List<PatchSet> patchSets = new ArrayList<>();
+
+ db.changes().beginTransaction(change.getId());
+ try {
+ for (RevisionInfo r : revisions) {
+ String origRef = r.ref;
+ ObjectId id = repo.resolve(origRef);
+ if (id == null) {
+ // already replayed?
+ continue;
+ }
+ RevCommit commit = rw.parseCommit(id);
+
+ PatchSet ps = new PatchSet(new PatchSet.Id(change.getId(), r._number));
+ patchSets.add(ps);
+
+ ps.setUploader(accountUtil.resolveUser(r.uploader));
+ ps.setCreatedOn(r.created);
+ ps.setRevision(new RevId(commit.name()));
+ ps.setDraft(r.draft != null && r.draft);
+
+ PatchSetInfo info = patchSetInfoFactory.get(commit, ps.getId());
+ if (changeInfo.currentRevision.equals(info.getRevId())) {
+ change.setCurrentPatchSet(info);
+ }
+
+ ChangeUtil.insertAncestors(db, ps.getId(), commit);
+
+ renameRef(repo, origRef, ps);
+ }
+
+ db.patchSets().insert(patchSets);
+ db.commit();
+ } finally {
+ db.rollback();
+ }
+ }
+
+ private static void sortRevisionInfoByNumber(List<RevisionInfo> list) {
+ Collections.sort(list, new Comparator<RevisionInfo>() {
+ @Override
+ public int compare(RevisionInfo a, RevisionInfo b) {
+ return a._number - b._number;
+ }
+ });
+ }
+
+ private void renameRef(Repository repo, String origRef, PatchSet ps)
+ throws IOException {
+ String ref = ps.getId().toRefName();
+ if (ref.equals(origRef)) {
+ return;
+ }
+
+ createRef(repo, ps);
+ deleteRef(repo, ps, origRef);
+ }
+
+ private void createRef(Repository repo, PatchSet ps) throws IOException {
+ String ref = ps.getId().toRefName();
+ RefUpdate ru = repo.updateRef(ref);
+ ru.setForceUpdate(true);
+ ru.setExpectedOldObjectId(ObjectId.zeroId());
+ ru.setNewObjectId(ObjectId.fromString(ps.getRevision().get()));
+ RefUpdate.Result result = ru.update();
+ switch (result) {
+ case NEW:
+ case FORCED:
+ case FAST_FORWARD:
+ return;
+ default:
+ throw new IOException(String.format("Failed to create ref %s", ref));
+ }
+ }
+
+ private void deleteRef(Repository repo, PatchSet ps, String ref)
+ throws IOException {
+ RefUpdate ru = repo.updateRef(ref);
+ ru.setForceUpdate(true);
+ ru.setExpectedOldObjectId(ObjectId.fromString(ps.getRevision().get()));
+ ru.setNewObjectId(ObjectId.zeroId());
+ RefUpdate.Result result = ru.update();
+ switch (result) {
+ case FORCED:
+ return;
+ default:
+ throw new IOException(String.format("Failed to delete ref %s", ref));
+ }
+ }
+}