Support deletion of branches via REST

A branch can now be deleted by DELETE on
/projects/<project-name>/branches/<branch-id>.

Change-Id: I2c9af129f024cd2668a46dd2bd8848bd0bc0655c
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
Edwin Kempin 2013-06-06 13:20:01 +02:00
parent 882aef2721
commit 6ce96a1e89
4 changed files with 136 additions and 0 deletions

View File

@ -598,6 +598,24 @@ describes the created branch.
}
----
[[delete-branch]]
Delete Branch
~~~~~~~~~~~~~
[verse]
'DELETE /projects/link:#project-name[\{project-name\}]/branches/link:#branch-id[\{branch-id\}]'
Deletes a branch.
.Request
----
DELETE /projects/MyProject/branches/stable HTTP/1.0
----
.Response
----
HTTP/1.1 204 No Content
----
[[child-project-endpoints]]
Child Project Endpoints
-----------------------

View File

@ -15,6 +15,7 @@
package com.google.gerrit.server.project;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.server.project.ListBranches.BranchInfo;
import com.google.inject.TypeLiteral;
@ -32,4 +33,12 @@ public class BranchResource extends ProjectResource {
public BranchInfo getBranchInfo() {
return branchInfo;
}
public Branch.NameKey getBranchKey() {
return new Branch.NameKey(getNameKey(), branchInfo.ref);
}
public String getRef() {
return branchInfo.ref;
}
}

View File

@ -0,0 +1,108 @@
// Copyright (C) 2013 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.server.project;
import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.DeleteBranch.Input;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class DeleteBranch implements RestModifyView<BranchResource, Input>{
private static final Logger log = LoggerFactory.getLogger(CreateBranch.class);
static class Input {
}
private final IdentifiedUser identifiedUser;
private final GitRepositoryManager repoManager;
private final Provider<ReviewDb> dbProvider;
private final GitReferenceUpdated referenceUpdated;
private final ChangeHooks hooks;
@Inject
DeleteBranch(IdentifiedUser identifiedUser, GitRepositoryManager repoManager,
Provider<ReviewDb> dbProvider, GitReferenceUpdated referenceUpdated,
ChangeHooks hooks) {
this.identifiedUser = identifiedUser;
this.repoManager = repoManager;
this.dbProvider = dbProvider;
this.referenceUpdated = referenceUpdated;
this.hooks = hooks;
}
@Override
public Object apply(BranchResource rsrc, Input input) throws AuthException,
ResourceConflictException, OrmException, IOException {
if (!rsrc.getControl().controlForRef(rsrc.getBranchKey()).canDelete()) {
throw new AuthException("Cannot delete branch");
}
if (dbProvider.get().changes().byBranchOpenAll(rsrc.getBranchKey())
.iterator().hasNext()) {
throw new ResourceConflictException("branch " + rsrc.getBranchKey()
+ " has open changes");
}
Repository r = repoManager.openRepository(rsrc.getNameKey());
try {
RefUpdate.Result result;
RefUpdate u;
try {
u = r.updateRef(rsrc.getRef());
u.setForceUpdate(true);
result = u.delete();
} catch (IOException e) {
log.error("Cannot delete " + rsrc.getBranchKey(), e);
throw e;
}
switch (result) {
case NEW:
case NO_CHANGE:
case FAST_FORWARD:
case FORCED:
referenceUpdated.fire(rsrc.getNameKey(), u);
hooks.doRefUpdatedHook(rsrc.getBranchKey(), u, identifiedUser.getAccount());
break;
case REJECTED_CURRENT_BRANCH:
log.warn("Cannot delete " + rsrc.getBranchKey() + ": " + result.name());
throw new ResourceConflictException("cannot delete current branch");
default:
log.error("Cannot delete " + rsrc.getBranchKey() + ": " + result.name());
throw new ResourceConflictException("cannot delete branch: " + result.name());
}
} finally {
r.close();
}
return Response.none();
}
}

View File

@ -55,6 +55,7 @@ public class Module extends RestApiModule {
child(PROJECT_KIND, "branches").to(BranchesCollection.class);
put(BRANCH_KIND).to(PutBranch.class);
get(BRANCH_KIND).to(GetBranch.class);
delete(BRANCH_KIND).to(DeleteBranch.class);
install(new FactoryModuleBuilder().build(CreateBranch.Factory.class));
child(PROJECT_KIND, "dashboards").to(DashboardsCollection.class);