Merge "Fix underlining of heading in REST documentation"
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java b/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java
index c5c5f42..341081f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/AddApprovalsStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/AddApprovalsStep.java
index 7a71153..f5afd95 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/AddApprovalsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/AddApprovalsStep.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
@@ -40,7 +40,7 @@
class AddApprovalsStep {
interface Factory {
- AddApprovalsStep create(Change change, ChangeInfo changeInfo);
+ AddApprovalsStep create(Change change, ChangeInfo changeInfo, boolean resume);
}
private final AccountUtil accountUtil;
@@ -50,6 +50,7 @@
private final ChangeControl.GenericFactory changeControlFactory;
private final Change change;
private final ChangeInfo changeInfo;
+ private final boolean resume;
@Inject
public AddApprovalsStep(AccountUtil accountUtil,
@@ -58,7 +59,8 @@
IdentifiedUser.GenericFactory genericUserFactory,
ChangeControl.GenericFactory changeControlFactory,
@Assisted Change change,
- @Assisted ChangeInfo changeInfo) {
+ @Assisted ChangeInfo changeInfo,
+ @Assisted boolean resume) {
this.accountUtil = accountUtil;
this.updateFactory = updateFactory;
this.db = db;
@@ -66,10 +68,16 @@
this.changeControlFactory = changeControlFactory;
this.change = change;
this.changeInfo = changeInfo;
+ this.resume = resume;
}
void add() throws OrmException, NoSuchChangeException, IOException,
NoSuchAccountException {
+ if (resume) {
+ db.patchSetApprovals().delete(
+ db.patchSetApprovals().byChange(change.getId()));
+ }
+
List<PatchSetApproval> approvals = new ArrayList<>();
for (Entry<String, LabelInfo> e : changeInfo.labels.entrySet()) {
String labelName = e.getKey();
@@ -83,12 +91,16 @@
new PatchSetApproval.Key(change.currentPatchSetId(), user,
labelType.getLabelId()), a.value.shortValue(), a.date));
ChangeUpdate update = updateFactory.create(ctrl);
- update.putApproval(labelName, a.value.shortValue());
+ if (a.value != 0) {
+ update.putApproval(labelName, a.value.shortValue());
+ } else {
+ update.removeApproval(labelName);
+ }
update.commit();
}
}
}
- db.patchSetApprovals().upsert(approvals);
+ db.patchSetApprovals().insert(approvals);
}
private ChangeControl control(Change change, AccountInfo acc)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/AddHashtagsStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/AddHashtagsStep.java
index e0b668d..e40fc5e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/AddHashtagsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/AddHashtagsStep.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
@@ -35,7 +35,7 @@
class AddHashtagsStep {
interface Factory {
- AddHashtagsStep create(Change change, ChangeInfo changeInfo);
+ AddHashtagsStep create(Change change, ChangeInfo changeInfo, boolean resume);
}
private final HashtagsUtil hashtagsUtil;
@@ -43,26 +43,36 @@
private final ChangeControl.GenericFactory changeControlFactory;
private final Change change;
private final ChangeInfo changeInfo;
+ private final boolean resume;
@Inject
AddHashtagsStep(HashtagsUtil hashtagsUtil,
IdentifiedUser.GenericFactory genericUserFactory,
ChangeControl.GenericFactory changeControlFactory,
@Assisted Change change,
- @Assisted ChangeInfo changeInfo) {
+ @Assisted ChangeInfo changeInfo,
+ @Assisted boolean resume) {
this.hashtagsUtil = hashtagsUtil;
this.change = change;
this.changeInfo = changeInfo;
this.genericUserFactory = genericUserFactory;
this.changeControlFactory = changeControlFactory;
+ this.resume = resume;
}
void add() throws IllegalArgumentException, AuthException, IOException,
ValidationException, OrmException, NoSuchChangeException {
+ ChangeControl ctrl = control(change, changeInfo.owner);
+
+ if (resume) {
+ HashtagsInput input = new HashtagsInput();
+ input.remove = ctrl.getNotes().load().getHashtags();
+ hashtagsUtil.setHashtags(ctrl, input, false, false);
+ }
+
HashtagsInput input = new HashtagsInput();
input.add = new HashSet<>(changeInfo.hashtags);
- hashtagsUtil.setHashtags(control(change, changeInfo.owner),
- input, false, false);
+ hashtagsUtil.setHashtags(ctrl, input, false, false);
}
private ChangeControl control(Change change, AccountInfo acc)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ConfigureProjectStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ConfigureProjectStep.java
index 787ae3b..6aefa97 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ConfigureProjectStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ConfigureProjectStep.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ConfigureRepositoryStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ConfigureRepositoryStep.java
index ff35988..f3f4bef 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ConfigureRepositoryStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ConfigureRepositoryStep.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/GitFetchStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/GitFetchStep.java
index 22404a4..10e0642 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/GitFetchStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/GitFetchStep.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
@@ -65,6 +65,7 @@
case NEW:
case FAST_FORWARD:
case FORCED:
+ case NO_CHANGE:
break;
default:
throw new IOException(String.format(
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportInfo.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportInfo.java
index ce64c60..16be1c6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportInfo.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportInfo.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportJson.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportJson.java
index 9e63a37..b92db2b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportJson.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportJson.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
@@ -54,22 +54,28 @@
this.accountLoaderFactory = accountLoaderFactory;
}
- public ImportProjectInfo format(Input input) throws OrmException {
- ImportProjectInfo info = new ImportProjectInfo();
- info.from = input.from;
- info.parent = input.parent;
- info.imports = new ArrayList<>();
+ public ImportProjectInfo format(Input input, ImportProjectInfo info)
+ throws OrmException {
+ if (info == null) {
+ info = new ImportProjectInfo();
+ info.from = input.from;
+ info.parent = input.parent;
+ info.imports = new ArrayList<>();
+ }
+ info.imports.add(createImportInfo(input.user));
+ return info;
+ }
+
+ private ImportInfo createImportInfo(String remoteUser) throws OrmException {
AccountLoader accountLoader = accountLoaderFactory.create(true);
ImportInfo importInfo = new ImportInfo();
importInfo.timestamp = new Timestamp(TimeUtil.nowMs());
importInfo.user =
accountLoader.get(((IdentifiedUser) currentUser.get()).getAccountId());
- importInfo.remoteUser = input.user;
- info.imports.add(importInfo);
+ importInfo.remoteUser = remoteUser;
accountLoader.fill();
-
- return info;
+ return importInfo;
}
public static void persist(LockFile lockFile, ImportProjectInfo info,
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
index 2a9d057..eb79abb 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
@@ -22,7 +22,6 @@
import com.google.gerrit.extensions.annotations.PluginData;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.restapi.BadRequestException;
-import com.google.gerrit.extensions.restapi.NotImplementedException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestApiException;
@@ -64,6 +63,21 @@
public String user;
public String pass;
public String parent;
+
+ private void validate() throws BadRequestException {
+ if (Strings.isNullOrEmpty(from)) {
+ throw new BadRequestException("from is required");
+ }
+ if (!(new UrlValidator(UrlValidator.ALLOW_LOCAL_URLS)).isValid(from)) {
+ throw new BadRequestException("from must be a valid URL");
+ }
+ if (Strings.isNullOrEmpty(user)) {
+ throw new BadRequestException("user is required");
+ }
+ if (Strings.isNullOrEmpty(pass)) {
+ throw new BadRequestException("pass is required");
+ }
+ }
}
interface Factory {
@@ -86,7 +100,7 @@
private final Project.NameKey project;
private Project.NameKey parent;
- private Writer err = null;
+ private Writer err;
@Inject
ImportProject(
@@ -117,6 +131,7 @@
void setErr(Writer err) {
this.err = err;
}
+
@Override
public Response<String> apply(ConfigResource rsrc, Input input)
throws RestApiException, OrmException, IOException, ValidationException,
@@ -124,22 +139,10 @@
if (input == null) {
input = new Input();
}
- if (Strings.isNullOrEmpty(input.from)) {
- throw new BadRequestException("from is required");
- }
- if (!(new UrlValidator(UrlValidator.ALLOW_LOCAL_URLS)).isValid(input.from)) {
- throw new BadRequestException("from must be a valid URL");
- }
- if (Strings.isNullOrEmpty(input.user)) {
- throw new BadRequestException("user is required");
- }
- if (Strings.isNullOrEmpty(input.pass)) {
- throw new BadRequestException("pass is required");
- }
LockFile lockFile = lockForImport(project);
try {
- return apply(lockFile, input, false);
+ return apply(lockFile, input, null);
} finally {
lockFile.unlock();
}
@@ -158,33 +161,35 @@
input.from = info.from;
input.parent = info.parent;
- return apply(lockFile, input, true);
+ return apply(lockFile, input, info);
} finally {
lockFile.unlock();
}
}
- private Response<String> apply(LockFile lockFile, Input input, boolean resume)
+ private Response<String> apply(LockFile lockFile, Input input, ImportProjectInfo info)
throws RestApiException, OrmException, IOException, ValidationException,
GitAPIException, NoSuchChangeException, NoSuchAccountException {
- if (resume) {
- throw new NotImplementedException();
- }
+ boolean resume = info != null;
+
+ input.validate();
ProgressMonitor pm = err != null ? new TextProgressMonitor(err) :
NullProgressMonitor.INSTANCE;
+ checkProjectInSource(input, pm);
+
try {
setParentProjectName(input, pm);
checkPreconditions(pm);
- Repository repo = openRepoStep.open(project, pm);
+ Repository repo = openRepoStep.open(project, resume, pm);
try {
- ImportJson.persist(lockFile, importJson.format(input), pm);
+ ImportJson.persist(lockFile, importJson.format(input, info), pm);
configRepoStep.configure(repo, project, input.from, pm);
gitFetchStep.fetch(input.user, input.pass, repo, pm);
configProjectStep.configure(project, parent, pm);
replayChangesFactory.create(input.from, input.user, input.pass, repo,
- project, pm)
+ project, resume, pm)
.replay();
} finally {
repo.close();
@@ -205,6 +210,13 @@
return Response.<String> ok("OK");
}
+ private void checkProjectInSource(Input input, ProgressMonitor pm)
+ throws IOException, BadRequestException {
+ pm.beginTask("Check source project", 1);
+ new RemoteApi(input.from, input.user, input.pass).getProject(project.get());
+ updateAndEnd(pm);
+ }
+
private void setParentProjectName(Input input, ProgressMonitor pm)
throws IOException, BadRequestException {
pm.beginTask("Set parent project", 1);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/InsertLinkToOriginalChangeStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/InsertLinkToOriginalChangeStep.java
index 0205745..fe04784 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/InsertLinkToOriginalChangeStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/InsertLinkToOriginalChangeStep.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
@@ -44,10 +44,11 @@
private final String fromGerrit;
private final Change change;
private final ChangeInfo changeInfo;
+ private final boolean resume;
interface Factory {
InsertLinkToOriginalChangeStep create(String fromGerrit, Change change,
- ChangeInfo changeInfo);
+ ChangeInfo changeInfo, boolean resume);
}
@Inject
@@ -59,7 +60,8 @@
ChangeMessagesUtil cmUtil,
@Assisted String fromGerrit,
@Assisted Change change,
- @Assisted ChangeInfo changeInfo) {
+ @Assisted ChangeInfo changeInfo,
+ @Assisted boolean resume) {
this.currentUser = currentUser;
this.updateFactory = updateFactory;
this.genericUserFactory = genericUserFactory;
@@ -69,10 +71,12 @@
this.fromGerrit = fromGerrit;
this.change = change;
this.changeInfo = changeInfo;
+ this.resume = resume;
}
void insert() throws NoSuchChangeException, OrmException, IOException {
- insertMessage(change, "Imported from " + changeUrl(changeInfo));
+ insertMessage(change, (resume ? "Resumed import of " : "Imported from ")
+ + changeUrl(changeInfo));
}
private String changeUrl(ChangeInfo c) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/OpenRepositoryStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/OpenRepositoryStep.java
index 16eef2b..8b347a1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/OpenRepositoryStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/OpenRepositoryStep.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
@@ -50,15 +50,23 @@
this.projectCreationValidationListeners = projectCreationValidationListeners;
}
- Repository open(Project.NameKey name, ProgressMonitor pm)
+ Repository open(Project.NameKey name, boolean resume, ProgressMonitor pm)
throws ResourceConflictException, IOException {
pm.beginTask("Open repository", 1);
try {
- git.openRepository(name);
- throw new ResourceConflictException(format(
- "repository %s already exists", name.get()));
+ Repository repo = git.openRepository(name);
+ if (resume) {
+ return repo;
+ } else {
+ throw new ResourceConflictException(format(
+ "repository %s already exists", name.get()));
+ }
} catch (RepositoryNotFoundException e) {
// Project doesn't exist
+ if (resume) {
+ throw new ResourceConflictException(format(
+ "repository %s does not exist", name.get()));
+ }
}
beforeCreateProject(name);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ProgressMonitorUtil.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ProgressMonitorUtil.java
index 51b1a49..209d14e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ProgressMonitorUtil.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ProgressMonitorUtil.java
@@ -1,16 +1,17 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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 org.eclipse.jgit.lib.ProgressMonitor;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java
index d684cbe..aca1b61 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
@@ -23,7 +23,6 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.ConfigResource;
import com.google.gerrit.server.project.NoSuchChangeException;
-import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.validators.ValidationException;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
@@ -56,7 +55,7 @@
@Option(name = "--parent", required = false, metaVar = "NAME",
usage = "name of parent project in target system")
- private ProjectControl parent;
+ private String parent;
@Option(name = "--quiet", usage = "suppress progress messages")
private boolean quiet;
@@ -76,8 +75,8 @@
input.from = url;
input.user = user;
input.pass = readPassword();
- if (parent != null) {
- input.parent = parent.getProject().getName();
+ if (!Strings.isNullOrEmpty(parent)) {
+ input.parent = parent;
}
try {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/RemoteApi.java b/src/main/java/com/googlesource/gerrit/plugins/importer/RemoteApi.java
index 5d20f01..d48ca5d 100755
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/RemoteApi.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/RemoteApi.java
@@ -105,6 +105,12 @@
throw new BadRequestException(
"invalid credentials: accessing source system failed with 401 Unauthorized");
}
+ if (r.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
+ throw new BadRequestException(
+ "Project not found or missing permissions for accessing the project:"
+ + " accessing source system failed with 404 Not found");
+ }
+
if (r.getStatusCode() < 200 || 300 <= r.getStatusCode()) {
throw new IOException(String.format(
"Unexpected response code for %s on %s : %s", method.name(),
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 e320d64..42e1e43 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
@@ -1,20 +1,22 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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.common.collect.Iterators;
import com.google.gerrit.common.errors.NoSuchAccountException;
+import com.google.gerrit.extensions.client.ChangeStatus;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Branch;
@@ -23,9 +25,12 @@
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.project.NoSuchChangeException;
+import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.validators.ValidationException;
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.lib.Constants;
@@ -46,6 +51,7 @@
@Assisted("password") String password,
Repository repo,
Project.NameKey name,
+ boolean resume,
ProgressMonitor pm);
}
@@ -58,11 +64,12 @@
private final AccountUtil accountUtil;
private final ReviewDb db;
private final ChangeIndexer indexer;
+ private final Provider<InternalChangeQuery> queryProvider;
private final String fromGerrit;
private final RemoteApi api;
private final Repository repo;
private final Project.NameKey name;
-
+ private final boolean resume;
private final ProgressMonitor pm;
@Inject
@@ -76,12 +83,14 @@
AccountUtil accountUtil,
ReviewDb db,
ChangeIndexer indexer,
- @Assisted ProgressMonitor pm,
+ Provider<InternalChangeQuery> queryProvider,
@Assisted("from") String fromGerrit,
@Assisted("user") String user,
@Assisted("password") String password,
@Assisted Repository repo,
- @Assisted Project.NameKey name) {
+ @Assisted Project.NameKey name,
+ @Assisted boolean resume,
+ @Assisted ProgressMonitor pm) {
this.replayRevisionsFactory = replayRevisionsFactory;
this.replayInlineCommentsFactory = replayInlineCommentsFactory;
this.replayMessagesFactory = replayMessagesFactory;
@@ -91,11 +100,13 @@
this.accountUtil = accountUtil;
this.db = db;
this.indexer = indexer;
+ this.queryProvider = queryProvider;
this.fromGerrit = fromGerrit;
this.api = new RemoteApi(fromGerrit, user, password);
this.repo = repo;
this.name = name;
this.pm = pm;
+ this.resume = resume;
}
void replay() throws IOException, OrmException,
@@ -119,20 +130,45 @@
private void replayChange(RevWalk rw, ChangeInfo c)
throws IOException, OrmException, NoSuchAccountException,
NoSuchChangeException, RestApiException, ValidationException {
- Change change = createChange(c);
+ if (c.status == ChangeStatus.DRAFT) {
+ // no import of draft changes
+ return;
+ }
+
+ Change change = resume ? findChange(c) : null;
+ boolean resumeChange;
+ if (change == null) {
+ resumeChange = false;
+ change = createChange(c);
+ } else {
+ resumeChange = true;
+ }
replayRevisionsFactory.create(repo, rw, change, c).replay();
- db.changes().insert(Collections.singleton(change));
+ upsertChange(resumeChange, change, c);
- replayInlineCommentsFactory.create(change, c, api).replay();
- replayMessagesFactory.create(change, c).replay();
- addApprovalsFactory.create(change, c).add();
- addHashtagsFactory.create(change, c).add();
+ replayInlineCommentsFactory.create(change, c, api, resumeChange).replay();
+ replayMessagesFactory.create(change, c, resumeChange).replay();
+ addApprovalsFactory.create(change, c, resume).add();
+ addHashtagsFactory.create(change, c, resumeChange).add();
- insertLinkToOriginalFactory.create(fromGerrit,change, c).insert();
+ insertLinkToOriginalFactory.create(fromGerrit,change, c, resumeChange).insert();
indexer.index(db, change);
}
+ private Change findChange(ChangeInfo c) throws OrmException {
+ List<Change> changes = ChangeData.asChanges(
+ queryProvider.get().byBranchKey(
+ new Branch.NameKey(name, fullName(c.branch)),
+ new Change.Key(c.changeId)));
+ if (changes.isEmpty()) {
+ return null;
+ } else {
+ return db.changes().get(
+ Iterators.getOnlyElement(changes.iterator()).getId());
+ }
+ }
+
private Change createChange(ChangeInfo c) throws OrmException,
NoSuchAccountException {
Change.Id changeId = new Change.Id(db.nextChangeId());
@@ -147,6 +183,16 @@
return change;
}
+ private void upsertChange(boolean resumeChange, Change change, ChangeInfo c)
+ throws OrmException {
+ if (resumeChange) {
+ change.setStatus(Change.Status.forChangeStatus(c.status));
+ change.setTopic(c.topic);
+ change.setLastUpdatedOn(c.updated);
+ }
+ db.changes().upsert(Collections.singleton(change));
+ }
+
private static String fullName(String branch) {
if (branch.startsWith(Constants.R_HEADS)) {
return branch;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java
index 815460e..1e2fa12 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java
@@ -1,84 +1,99 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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.common.collect.Ordering;
-import com.google.common.collect.Table;
-import com.google.common.collect.TreeBasedTable;
+import static com.google.gerrit.server.PatchLineCommentsUtil.setCommentRevId;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.common.errors.NoSuchAccountException;
-import com.google.gerrit.extensions.api.changes.ReviewInput;
-import com.google.gerrit.extensions.api.changes.ReviewInput.NotifyHandling;
+import com.google.gerrit.extensions.client.Side;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
+import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.CommentRange;
+import com.google.gerrit.reviewdb.client.Patch;
+import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.PostReview;
-import com.google.gerrit.server.change.RevisionResource;
+import com.google.gerrit.server.PatchLineCommentsUtil;
+import com.google.gerrit.server.notedb.ChangeUpdate;
+import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
-import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
class ReplayInlineCommentsStep {
interface Factory {
ReplayInlineCommentsStep create(Change change, ChangeInfo changeInfo,
- RemoteApi api);
+ RemoteApi api, boolean resume);
}
private final AccountUtil accountUtil;
private final ReviewDb db;
- private final Provider<PostReview> postReview;
private final IdentifiedUser.GenericFactory genericUserFactory;
private final ChangeControl.GenericFactory changeControlFactory;
+ private final ChangeUpdate.Factory updateFactory;
+ private final PatchLineCommentsUtil plcUtil;
+ private final PatchListCache patchListCache;
private final Change change;
private final ChangeInfo changeInfo;
private final RemoteApi api;
+ private final boolean resume;
@Inject
public ReplayInlineCommentsStep(AccountUtil accountUtil,
ReviewDb db,
- Provider<PostReview> postReview,
IdentifiedUser.GenericFactory genericUserFactory,
ChangeControl.GenericFactory changeControlFactory,
+ ChangeUpdate.Factory updateFactory,
+ PatchLineCommentsUtil plcUtil,
+ PatchListCache patchListCache,
@Assisted Change change,
@Assisted ChangeInfo changeInfo,
- @Assisted RemoteApi api) {
+ @Assisted RemoteApi api,
+ @Assisted boolean resume) {
this.accountUtil = accountUtil;
this.db = db;
- this.postReview = postReview;
this.genericUserFactory = genericUserFactory;
this.changeControlFactory = changeControlFactory;
+ this.updateFactory = updateFactory;
+ this.plcUtil = plcUtil;
+ this.patchListCache = patchListCache;
this.change = change;
this.changeInfo = changeInfo;
this.api = api;
+ this.resume = resume;
}
void replay() throws RestApiException, OrmException, IOException,
@@ -86,62 +101,95 @@
for (PatchSet ps : db.patchSets().byChange(change.getId())) {
Iterable<CommentInfo> comments = api.getComments(
changeInfo._number, ps.getRevision().get());
-
- Table<Timestamp, Account.Id, List<CommentInfo>> t = TreeBasedTable.create(
- Ordering.natural(), new Comparator<Account.Id>() {
- @Override
- public int compare(Account.Id a1, Account.Id a2) {
- return a1.get() - a2.get();
- }}
- );
-
- for (CommentInfo comment : comments) {
- Account.Id id = accountUtil.resolveUser(comment.author);
- List<CommentInfo> ci = t.get(comment.updated, id);
- if (ci == null) {
- ci = new ArrayList<>();
- t.put(comment.updated, id, ci);
- }
- ci.add(comment);
+ if (resume) {
+ comments = filterComments(ps, comments);
}
- for (Timestamp ts : t.rowKeySet()) {
- for (Map.Entry<Account.Id, List<CommentInfo>> e : t.row(ts).entrySet()) {
- postComments(change, ps, e.getValue(), e.getKey(), ts);
- }
+ Multimap<Account.Id, CommentInfo> commentsByAuthor = ArrayListMultimap.create();
+ for (CommentInfo comment : comments) {
+ Account.Id id = accountUtil.resolveUser(comment.author);
+ commentsByAuthor.put(id, comment);
+ }
+
+ for (Account.Id id : commentsByAuthor.keySet()) {
+ insertComments(ps, id, commentsByAuthor.get(id));
}
}
}
- private void postComments(Change change, PatchSet ps,
- List<CommentInfo> comments, Account.Id author, Timestamp ts)
- throws RestApiException, OrmException, IOException, NoSuchChangeException {
- ReviewInput input = new ReviewInput();
- input.notify = NotifyHandling.NONE;
- input.comments = new HashMap<>();
-
- for (CommentInfo comment : comments) {
- if (!input.comments.containsKey(comment.path)) {
- input.comments.put(comment.path,
- new ArrayList<ReviewInput.CommentInput>());
- }
-
- ReviewInput.CommentInput commentInput = new ReviewInput.CommentInput();
- commentInput.id = comment.id;
- commentInput.inReplyTo = comment.inReplyTo;
- commentInput.line = comment.line;
- commentInput.message = comment.message;
- commentInput.path = comment.path;
- commentInput.range = comment.range;
- commentInput.side = comment.side;
- commentInput.updated = comment.updated;
-
- input.comments.get(comment.path).add(commentInput);
+ private Iterable<CommentInfo> filterComments(PatchSet ps,
+ Iterable<CommentInfo> comments) throws OrmException {
+ Set<String> existingUuids = new HashSet<>();
+ for (PatchLineComment c : db.patchComments().byPatchSet(ps.getId())) {
+ existingUuids.add(c.getKey().get());
}
- postReview.get().apply(
- new RevisionResource(new ChangeResource(control(change, author)), ps),
- input, ts);
+ Iterator<CommentInfo> it = comments.iterator();
+ while (it.hasNext()) {
+ CommentInfo c = it.next();
+ if (existingUuids.contains(Url.decode(c.id))) {
+ it.remove();
+ }
+ }
+ return comments;
+ }
+
+ private void insertComments(PatchSet ps, Account.Id author,
+ Collection<CommentInfo> comments) throws OrmException, IOException,
+ NoSuchChangeException {
+ ChangeControl ctrl = control(change, author);
+
+ Map<String, PatchLineComment> drafts = scanDraftComments(ctrl, ps);
+
+ List<PatchLineComment> del = Lists.newArrayList();
+ List<PatchLineComment> ups = Lists.newArrayList();
+
+ for (CommentInfo c : comments) {
+ String parent = Url.decode(c.inReplyTo);
+ PatchLineComment e = drafts.remove(Url.decode(c.id));
+ if (e == null) {
+ e = new PatchLineComment(
+ new PatchLineComment.Key(
+ new Patch.Key(ps.getId(), c.path),
+ Url.decode(c.id)),
+ c.line != null ? c.line : 0,
+ author, parent, c.updated);
+ } else if (parent != null) {
+ e.setParentUuid(parent);
+ }
+ e.setStatus(PatchLineComment.Status.PUBLISHED);
+ e.setWrittenOn(c.updated);
+ e.setSide(c.side == Side.PARENT ? (short) 0 : (short) 1);
+ setCommentRevId(e, patchListCache, change, ps);
+ e.setMessage(c.message);
+ if (c.range != null) {
+ e.setRange(new CommentRange(
+ c.range.startLine,
+ c.range.startCharacter,
+ c.range.endLine,
+ c.range.endCharacter));
+ e.setLine(c.range.endLine);
+ }
+ ups.add(e);
+ }
+
+ del.addAll(drafts.values());
+ ChangeUpdate update = updateFactory.create(ctrl, TimeUtil.nowTs());
+ update.setPatchSetId(ps.getId());
+ plcUtil.deleteComments(db, update, del);
+ plcUtil.upsertComments(db, update, ups);
+ update.commit();
+ }
+
+ private Map<String, PatchLineComment> scanDraftComments(ChangeControl ctrl,
+ PatchSet ps) throws OrmException {
+ Map<String, PatchLineComment> drafts = Maps.newHashMap();
+ for (PatchLineComment c : plcUtil.draftByPatchSetAuthor(db, ps.getId(),
+ ((IdentifiedUser) ctrl.getCurrentUser()).getAccountId(),
+ ctrl.getNotes())) {
+ drafts.put(c.getKey().get(), c);
+ }
+ return drafts;
}
private ChangeControl control(Change change, Account.Id id)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayMessagesStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayMessagesStep.java
index 778e8c3..1b2d5e8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayMessagesStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayMessagesStep.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
@@ -38,7 +38,8 @@
class ReplayMessagesStep {
interface Factory {
- ReplayMessagesStep create(Change change, ChangeInfo changeInfo);
+ ReplayMessagesStep create(Change change, ChangeInfo changeInfo,
+ boolean resume);
}
private final AccountUtil accountUtil;
@@ -49,6 +50,7 @@
private final ChangeControl.GenericFactory changeControlFactory;
private final Change change;
private final ChangeInfo changeInfo;
+ private final boolean resume;
@Inject
public ReplayMessagesStep(AccountUtil accountUtil,
@@ -58,7 +60,8 @@
ChangeControl.GenericFactory changeControlFactory,
ReviewDb db,
@Assisted Change change,
- @Assisted ChangeInfo changeInfo) {
+ @Assisted ChangeInfo changeInfo,
+ @Assisted boolean resume) {
this.accountUtil = accountUtil;
this.updateFactory = updateFactory;
this.cmUtil = cmUtil;
@@ -67,18 +70,25 @@
this.changeControlFactory = changeControlFactory;
this.change = change;
this.changeInfo = changeInfo;
+ this.resume = resume;
}
void replay() throws NoSuchAccountException, NoSuchChangeException,
OrmException, IOException {
for (ChangeMessageInfo msg : changeInfo.messages) {
+ ChangeMessage.Key msgKey = new ChangeMessage.Key(change.getId(), msg.id);
+ if (resume && db.changeMessages().get(msgKey) != null) {
+ // already replayed
+ continue;
+ }
+
Timestamp ts = msg.date;
if (msg.author != null) {
Account.Id userId = accountUtil.resolveUser(msg.author);
ChangeUpdate update = updateFactory.create(control(change, userId), ts);
ChangeMessage cmsg =
- new ChangeMessage(new ChangeMessage.Key(change.getId(), msg.id),
- userId, ts, new PatchSet.Id(change.getId(), msg._revisionNumber));
+ new ChangeMessage(msgKey, userId, ts, new PatchSet.Id(
+ change.getId(), msg._revisionNumber));
cmsg.setMessage(msg.message);
cmUtil.addChangeMessage(db, update, cmsg);
update.commit();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
index e37dff8..8d5b152 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
@@ -1,16 +1,16 @@
-//Copyright (C) 2015 The Android Open Source Project
+// 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
+// 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
+// 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.
+// 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;
@@ -81,15 +81,24 @@
db.changes().beginTransaction(change.getId());
try {
for (RevisionInfo r : revisions) {
+ if (r.draft != null && r.draft) {
+ // no import of draft patch sets
+ continue;
+ }
+ PatchSet ps = new PatchSet(new PatchSet.Id(change.getId(), r._number));
+ String newRef = ps.getId().toRefName();
+ if (repo.resolve(newRef) != null) {
+ // already replayed
+ continue;
+ }
+
String origRef = imported(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));
diff --git a/src/main/resources/Documentation/cmd-project.md b/src/main/resources/Documentation/cmd-project.md
index de4a369..e02cbcd 100644
--- a/src/main/resources/Documentation/cmd-project.md
+++ b/src/main/resources/Documentation/cmd-project.md
@@ -13,7 +13,7 @@
--user <USER> | -u <USER> \
--pass - | <PASS> \
[--parent <NAME>] \
- [--quiet]
+ [--quiet] \
<NAME>
```