summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Hamalainen <mika.hamalainen@accenture.com>2011-09-06 13:04:00 +0300
committerMika Hamalainen <mika.hamalainen@accenture.com>2011-09-06 13:04:00 +0300
commitbdea488805bf0ea2d797646b663eb7e0619e1e16 (patch)
tree9acf9b94ad2f6c4d77705e029ea9a7f2389ccdf2
parenta18cf2ff982a241d03527af0689bbc000cced4f2 (diff)
Unstaging support for topics
Topics can be now removed from staging. The topic needs to be in STAGED state and the current user must be able to abandon the topic for the remove from staging button to be visible. Each change is separately set to NEW status and the staging branch is rebuild. Change-Id: If8ef39ba9d40e97bd3170a46047041b4939dc290
-rw-r--r--gerrit-common/src/main/java/com/google/gerrit/common/data/TopicManageService.java3
-rw-r--r--gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeSetComplexDisclosurePanel.java18
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicDetailFactory.java5
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicManageServiceImpl.java10
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicModule.java1
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/UnstageAction.java155
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/TopicUtil.java26
7 files changed, 213 insertions, 5 deletions
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/TopicManageService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/TopicManageService.java
index a12d16dc04..697866ec54 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/TopicManageService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/TopicManageService.java
@@ -40,4 +40,7 @@ public interface TopicManageService extends RemoteJsonService {
@SignInRequired
void stage(ChangeSet.Id changeSetId, AsyncCallback<TopicDetail> callback);
+
+ @SignInRequired
+ void unstage(ChangeSet.Id changeSetId, AsyncCallback<TopicDetail> callback);
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeSetComplexDisclosurePanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeSetComplexDisclosurePanel.java
index ea09296e89..254876da95 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeSetComplexDisclosurePanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeSetComplexDisclosurePanel.java
@@ -259,6 +259,24 @@ class ChangeSetComplexDisclosurePanel extends CommonComplexDisclosurePanel {
actionsPanel.add(b);
}
+ if (topicDetail.canUnstage()) {
+ final Button b = new Button(Util.C.buttonUnstagingChange());
+ b.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ b.setEnabled(false);
+ Util.T_MANAGE_SVC.unstage(changeSet.getId(),
+ new GerritCallback<TopicDetail>() {
+ @Override
+ public void onSuccess(TopicDetail result) {
+ topicScreen.update(result);
+ }
+ });
+ }
+ });
+ actionsPanel.add(b);
+ }
+
if (topicDetail.canRestore()) {
final Button b = new Button(Util.TC.buttonRestoreTopicBegin());
b.addClickHandler(new ClickHandler() {
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicDetailFactory.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicDetailFactory.java
index a7ed068b9e..4c77e899ae 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicDetailFactory.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicDetailFactory.java
@@ -38,7 +38,6 @@ import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountInfoCacheFactory;
import com.google.gerrit.server.project.CanSubmitResult;
-import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchTopicException;
import com.google.gerrit.server.project.TopicControl;
@@ -64,7 +63,6 @@ public class TopicDetailFactory extends Handler<TopicDetail> {
}
private final ApprovalTypes approvalTypes;
- private final ChangeControl.Factory changeControlFactory;
private final TopicControl.Factory topicControlFactory;
private final TopicFunctionState.Factory functionState;
private final ChangeSetDetailFactory.Factory changeSetDetail;
@@ -81,7 +79,6 @@ public class TopicDetailFactory extends Handler<TopicDetail> {
TopicDetailFactory(final ApprovalTypes approvalTypes,
final TopicFunctionState.Factory functionState,
final ChangeSetDetailFactory.Factory changeSetDetail, final ReviewDb db,
- final ChangeControl.Factory changeControlFactory,
final TopicControl.Factory topicControlFactory,
final AccountInfoCacheFactory.Factory accountInfoCacheFactory,
final AnonymousUser anonymousUser,
@@ -90,7 +87,6 @@ public class TopicDetailFactory extends Handler<TopicDetail> {
this.functionState = functionState;
this.changeSetDetail = changeSetDetail;
this.db = db;
- this.changeControlFactory = changeControlFactory;
this.topicControlFactory = topicControlFactory;
this.anonymousUser = anonymousUser;
this.aic = accountInfoCacheFactory.create();
@@ -124,6 +120,7 @@ public class TopicDetailFactory extends Handler<TopicDetail> {
detail.setCanRevert(topic.getStatus() == AbstractEntity.Status.MERGED && control.canAddChangeSet());
detail.setCanSubmit(canSubmitResult == CanSubmitResult.OK);
detail.setCanStage(canStageResult == CanSubmitResult.OK);
+ detail.setCanUnstage(topic.getStatus() == AbstractEntity.Status.STAGED && control.canAbandon());
loadChangeSets();
loadMessages();
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicManageServiceImpl.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicManageServiceImpl.java
index 080f394d31..36ab6f5efc 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicManageServiceImpl.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicManageServiceImpl.java
@@ -26,18 +26,21 @@ class TopicManageServiceImpl implements TopicManageService {
private final RestoreTopic.Factory restoreTopicFactory;
private final RevertTopic.Factory revertTopicFactory;
private final StagingAction.Factory stagingActionFactory;
+ private final UnstageAction.Factory unstageActionFactory;
@Inject
TopicManageServiceImpl(final SubmitAction.Factory changeSetAction,
final AbandonTopic.Factory abandonTopicFactory,
final RestoreTopic.Factory restoreTopicFactory,
final RevertTopic.Factory revertTopicFactory,
- final StagingAction.Factory stagingActionFactory) {
+ final StagingAction.Factory stagingActionFactory,
+ final UnstageAction.Factory unstageActionFactory) {
this.submitAction = changeSetAction;
this.abandonTopicFactory = abandonTopicFactory;
this.restoreTopicFactory = restoreTopicFactory;
this.revertTopicFactory = revertTopicFactory;
this.stagingActionFactory = stagingActionFactory;
+ this.unstageActionFactory = unstageActionFactory;
}
public void submit(final ChangeSet.Id csid,
@@ -64,4 +67,9 @@ class TopicManageServiceImpl implements TopicManageService {
AsyncCallback<TopicDetail> callback) {
stagingActionFactory.create(changeSetId).to(callback);
}
+
+ public void unstage(ChangeSet.Id changeSetId,
+ AsyncCallback<TopicDetail> callback) {
+ unstageActionFactory.create(changeSetId).to(callback);
+ }
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicModule.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicModule.java
index 528c4b3b88..a75b41ed48 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicModule.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/TopicModule.java
@@ -40,6 +40,7 @@ public class TopicModule extends RpcServletModule {
factory(SubmitAction.Factory.class);
factory(IncludedInDetailHandler.Factory.class);
factory(StagingAction.Factory.class);
+ factory(UnstageAction.Factory.class);
}
});
rpc(TopicDetailServiceImpl.class);
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/UnstageAction.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/UnstageAction.java
new file mode 100644
index 0000000000..22e74db0af
--- /dev/null
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/topic/UnstageAction.java
@@ -0,0 +1,155 @@
+// Copyright (C) 2011 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.google.gerrit.httpd.rpc.topic;
+
+import com.google.gerrit.common.ChangeHookRunner;
+import com.google.gerrit.common.data.ApprovalTypes;
+import com.google.gerrit.common.data.TopicDetail;
+import com.google.gerrit.common.errors.NoSuchEntityException;
+import com.google.gerrit.httpd.rpc.Handler;
+import com.google.gerrit.reviewdb.Branch;
+import com.google.gerrit.reviewdb.Change;
+import com.google.gerrit.reviewdb.ChangeSet;
+import com.google.gerrit.reviewdb.ChangeSetElement;
+import com.google.gerrit.reviewdb.ReviewDb;
+import com.google.gerrit.reviewdb.Topic;
+import com.google.gerrit.server.ChangeUtil;
+import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.TopicUtil;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.MergeOp;
+import com.google.gerrit.server.git.MergeQueue;
+import com.google.gerrit.server.project.CanSubmitResult;
+import com.google.gerrit.server.project.ChangeControl;
+import com.google.gerrit.server.project.NoSuchChangeException;
+import com.google.gerrit.server.project.NoSuchRefException;
+import com.google.gerrit.server.project.NoSuchTopicException;
+import com.google.gerrit.server.project.TopicControl;
+import com.google.gerrit.server.workflow.TopicFunctionState;
+import com.google.gwtorm.client.OrmException;
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
+
+import org.eclipse.jgit.lib.Repository;
+
+import java.io.IOException;
+import java.util.List;
+
+
+class UnstageAction extends Handler<TopicDetail> {
+ interface Factory {
+ UnstageAction create(ChangeSet.Id changeSetId);
+ }
+
+ private final ReviewDb db;
+ private final MergeQueue merger;
+ private final ApprovalTypes approvalTypes;
+ private final IdentifiedUser user;
+ private final TopicDetailFactory.Factory topicDetailFactory;
+ private final ChangeControl.Factory changeControlFactory;
+ private final TopicControl.Factory topicControlFactory;
+ private final TopicFunctionState.Factory topicFunctionState;
+ private final MergeOp.Factory opFactory;
+ private final GitRepositoryManager gitManager;
+ private final ChangeHookRunner hooks;
+
+ private final ChangeSet.Id changeSetId;
+
+ @Inject
+ UnstageAction(final ReviewDb db, final MergeQueue mq,
+ final IdentifiedUser user,
+ final ApprovalTypes approvalTypes,
+ final TopicDetailFactory.Factory topicDetailFactory,
+ final ChangeControl.Factory changeControlFactory,
+ final TopicControl.Factory topicControlFactory,
+ final TopicFunctionState.Factory topicFunctionState,
+ final MergeOp.Factory opFactory,
+ final GitRepositoryManager gitManager,
+ final ChangeHookRunner hooks,
+ @Assisted final ChangeSet.Id changeSetId) {
+ this.db = db;
+ this.merger = mq;
+ this.approvalTypes = approvalTypes;
+ this.user = user;
+ this.changeControlFactory = changeControlFactory;
+ this.topicControlFactory = topicControlFactory;
+ this.topicDetailFactory = topicDetailFactory;
+ this.topicFunctionState = topicFunctionState;
+ this.opFactory = opFactory;
+ this.gitManager = gitManager;
+ this.hooks = hooks;
+
+ this.changeSetId = changeSetId;
+ }
+
+ @Override
+ public TopicDetail call() throws OrmException, NoSuchEntityException,
+ IllegalStateException, ChangeSetInfoNotAvailableException,
+ NoSuchTopicException, NoSuchChangeException {
+
+ final Topic.Id topicId = changeSetId.getParentKey();
+ final TopicControl topicControl =
+ topicControlFactory.validateFor(topicId);
+
+ CanSubmitResult result = topicControl.canStage(db, changeSetId,
+ changeControlFactory, approvalTypes, topicFunctionState);
+
+ Repository git = null;
+ if (result == CanSubmitResult.OK) {
+ try {
+ // Open a handle to Git repository.
+ git =
+ gitManager.openRepository(topicControl.getProject().getNameKey());
+
+ // Set topic status to NEW
+ TopicUtil.rejectStagedTopic(changeSetId, user, db, opFactory, merger,
+ git, hooks);
+
+ // Reject all changes.
+ final ChangeSet.Id changeSetId =
+ topicControl.getTopic().currChangeSetId();
+
+ final List<ChangeSetElement> changes =
+ db.changeSetElements().byChangeSet(changeSetId).toList();
+
+ for (ChangeSetElement changeSetElement: changes) {
+ final Change.Id changeId = changeSetElement.getChangeId();
+ final Change change = db.changes().get(changeId);
+ ChangeUtil.rejectStagedChange(change.currentPatchSetId(), user, db);
+ }
+
+ // Rebuild staging branch.
+ final Branch.NameKey branch = topicControl.getTopic().getDest();
+ ChangeUtil.rebuildStaging(branch, user, db, git, opFactory, merger,
+ hooks);
+ } catch (IOException e) {
+ throw new IllegalStateException(e.getMessage());
+ } catch (NoSuchRefException e) {
+ throw new IllegalStateException(e.getMessage());
+ } finally {
+ // Make sure that access to Git repository is closed.
+ if (git != null) {
+ git.close();
+ }
+ }
+ return topicDetailFactory.create(topicId).call();
+ } else {
+ // Report error message to user. User cannot move this change to staging.
+ // The problem is caused because of illegal stage of missing access
+ // rights.
+ throw new IllegalStateException(result.getMessage());
+ }
+ }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/TopicUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/TopicUtil.java
index 6aef58fb03..2befc26231 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/TopicUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/TopicUtil.java
@@ -146,6 +146,32 @@ public class TopicUtil {
}
}
+ public static void rejectStagedTopic(final ChangeSet.Id changeSetId,
+ final IdentifiedUser user, final ReviewDb db,
+ final MergeOp.Factory opFactory, final MergeQueue merger,
+ final Repository git, final ChangeHookRunner hooks) throws OrmException {
+ // Delete all STAGING approvals for the change set.
+ final ChangeSetApproval.Key stagingKey =
+ new ChangeSetApproval.Key(changeSetId, user.getAccountId(), STAGING);
+ db.changeSetApprovals().deleteKeys(Collections.singleton(stagingKey));
+
+ // Set topic state to NEW.
+ final Topic.Id topicId = changeSetId.getParentKey();
+ AtomicUpdate<Topic> atomicUpdate =
+ new AtomicUpdate<Topic>() {
+ @Override
+ public Topic update(Topic topic) {
+ if (topic.getStatus() == AbstractEntity.Status.INTEGRATING
+ || topic.getStatus() == AbstractEntity.Status.STAGED) {
+ topic.setStatus(AbstractEntity.Status.NEW);
+ TopicUtil.updated(topic);
+ }
+ return topic;
+ }
+ };
+ db.topics().atomicUpdate(topicId, atomicUpdate);
+ }
+
public static ChangeSetApproval createSubmitApproval(
final ChangeSet.Id changeSetId, final IdentifiedUser user, final ReviewDb db
) throws OrmException {