Support branch creation via REST
A new branch can be created by PUT on '/projects/<project-name>/branches/<ref>. The WebUI was adapted to use this new REST endpoint to create branches. The old RPC for creating a branch in ProjectAdminService was deleted. Change-Id: Id94bc4737eedde383507c7c567b3b6b102b105c5
This commit is contained in:
parent
94a928b9a9
commit
5c0d6b33ff
@ -560,6 +560,44 @@ describes the branch.
|
||||
}
|
||||
----
|
||||
|
||||
[[create-branch]]
|
||||
Create Branch
|
||||
~~~~~~~~~~~~~
|
||||
[verse]
|
||||
'PUT /projects/link:#project-name[\{project-name\}]/branches/link:#branch-id[\{branch-id\}]'
|
||||
|
||||
Creates a new branch.
|
||||
|
||||
In the request body additional data for the branch can be provided as
|
||||
link:#branch-input[BranchInput].
|
||||
|
||||
.Request
|
||||
----
|
||||
PUT /projects/MyProject/branches/stable HTTP/1.0
|
||||
Content-Type: application/json;charset=UTF-8
|
||||
|
||||
{
|
||||
"revision": "76016386a0d8ecc7b6be212424978bb45959d668"
|
||||
}
|
||||
----
|
||||
|
||||
As response a link:#branch-info[BranchInfo] entity is returned that
|
||||
describes the created branch.
|
||||
|
||||
.Response
|
||||
----
|
||||
HTTP/1.1 201 Created
|
||||
Content-Disposition: attachment
|
||||
Content-Type: application/json;charset=UTF-8
|
||||
|
||||
)]}'
|
||||
{
|
||||
"ref": "refs/heads/stable",
|
||||
"revision": "76016386a0d8ecc7b6be212424978bb45959d668",
|
||||
"can_delete": true
|
||||
}
|
||||
----
|
||||
|
||||
[[child-project-endpoints]]
|
||||
Child Project Endpoints
|
||||
-----------------------
|
||||
@ -968,6 +1006,24 @@ The `BranchInfo` entity contains information about a branch.
|
||||
Whether the calling user can delete this branch.
|
||||
|=========================
|
||||
|
||||
[[branch-input]]
|
||||
BranchInput
|
||||
~~~~~~~~~~~
|
||||
The `BranchInput` entity contains information for the creation of
|
||||
a new branch.
|
||||
|
||||
[options="header",width="50%",cols="1,^2,4"]
|
||||
|=======================
|
||||
|Field Name||Description
|
||||
|`ref` |optional|
|
||||
The name of the branch. The prefix `refs/heads/` can be
|
||||
omitted. +
|
||||
If set, must match the branch ID in the URL.
|
||||
|`revision`|optional|
|
||||
The base revision of the new branch. +
|
||||
If not set, `HEAD` will be used as base revision.
|
||||
|=======================
|
||||
|
||||
[[dashboard-info]]
|
||||
DashboardInfo
|
||||
~~~~~~~~~~~~~
|
||||
|
@ -56,11 +56,6 @@ public interface ProjectAdminService extends RemoteJsonService {
|
||||
void listBranches(Project.NameKey projectName,
|
||||
AsyncCallback<ListBranchesResult> callback);
|
||||
|
||||
@Audit
|
||||
@SignInRequired
|
||||
void addBranch(Project.NameKey projectName, String branchName,
|
||||
String startingRevision, AsyncCallback<AddBranchResult> callback);
|
||||
|
||||
@Audit
|
||||
@SignInRequired
|
||||
void deleteBranch(Project.NameKey projectName, Set<Branch.NameKey> ids,
|
||||
|
@ -19,12 +19,13 @@ import com.google.gerrit.client.ConfirmationDialog;
|
||||
import com.google.gerrit.client.ErrorDialog;
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.GitwebLink;
|
||||
import com.google.gerrit.client.projects.BranchInfo;
|
||||
import com.google.gerrit.client.projects.ProjectApi;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.rpc.ScreenLoadCallback;
|
||||
import com.google.gerrit.client.ui.BranchLink;
|
||||
import com.google.gerrit.client.ui.FancyFlexTable;
|
||||
import com.google.gerrit.client.ui.HintTextBox;
|
||||
import com.google.gerrit.common.data.AddBranchResult;
|
||||
import com.google.gerrit.common.data.ListBranchesResult;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
@ -185,62 +186,29 @@ public class ProjectBranchesScreen extends ProjectScreen {
|
||||
}
|
||||
|
||||
addBranch.setEnabled(false);
|
||||
Util.PROJECT_SVC.addBranch(getProjectKey(), branchName, rev,
|
||||
new GerritCallback<AddBranchResult>() {
|
||||
public void onSuccess(final AddBranchResult result) {
|
||||
addBranch.setEnabled(true);
|
||||
if (!result.hasError()) {
|
||||
nameTxtBox.setText("");
|
||||
irevTxtBox.setText("");
|
||||
display(result.getListBranchesResult().getBranches());
|
||||
} else {
|
||||
final AddBranchResult.Error error = result.getError();
|
||||
final String msg;
|
||||
switch (error.getType()) {
|
||||
case INVALID_NAME:
|
||||
selectAllAndFocus(nameTxtBox);
|
||||
msg = Gerrit.M.invalidBranchName(branchName);
|
||||
break;
|
||||
|
||||
case INVALID_REVISION:
|
||||
selectAllAndFocus(irevTxtBox);
|
||||
msg = Gerrit.M.invalidRevision(rev);
|
||||
break;
|
||||
|
||||
case BRANCH_CREATION_NOT_ALLOWED_UNDER_REFNAME_PREFIX:
|
||||
selectAllAndFocus(nameTxtBox);
|
||||
msg =
|
||||
Gerrit.M.branchCreationNotAllowedUnderRefnamePrefix(error
|
||||
.getRefname());
|
||||
break;
|
||||
|
||||
case BRANCH_ALREADY_EXISTS:
|
||||
selectAllAndFocus(nameTxtBox);
|
||||
msg = Gerrit.M.branchAlreadyExists(error.getRefname());
|
||||
break;
|
||||
|
||||
case BRANCH_CREATION_CONFLICT:
|
||||
selectAllAndFocus(nameTxtBox);
|
||||
msg =
|
||||
Gerrit.M.branchCreationConflict(branchName,
|
||||
error.getRefname());
|
||||
break;
|
||||
|
||||
default:
|
||||
msg =
|
||||
Gerrit.M.branchCreationFailed(branchName,
|
||||
error.toString());
|
||||
}
|
||||
new ErrorDialog(msg).center();
|
||||
}
|
||||
}
|
||||
|
||||
ProjectApi.createBranch(getProjectKey(), branchName, rev,
|
||||
new GerritCallback<BranchInfo>() {
|
||||
@Override
|
||||
public void onFailure(final Throwable caught) {
|
||||
public void onSuccess(BranchInfo result) {
|
||||
addBranch.setEnabled(true);
|
||||
super.onFailure(caught);
|
||||
nameTxtBox.setText("");
|
||||
irevTxtBox.setText("");
|
||||
Util.PROJECT_SVC.listBranches(getProjectKey(),
|
||||
new GerritCallback<ListBranchesResult>() {
|
||||
@Override
|
||||
public void onSuccess(ListBranchesResult result) {
|
||||
display(result.getBranches());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
addBranch.setEnabled(true);
|
||||
selectAllAndFocus(nameTxtBox);
|
||||
new ErrorDialog(caught.getMessage()).center();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void selectAllAndFocus(final TextBox textBox) {
|
||||
|
@ -0,0 +1,26 @@
|
||||
// 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.client.projects;
|
||||
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
|
||||
public class BranchInfo extends JavaScriptObject {
|
||||
public final native String ref() /*-{ return this.ref; }-*/;
|
||||
public final native String revision() /*-{ return this.revision; }-*/;
|
||||
public final native boolean canDelete() /*-{ return this['can_delete'] ? true : false; }-*/;
|
||||
|
||||
protected BranchInfo() {
|
||||
}
|
||||
}
|
@ -33,6 +33,15 @@ public class ProjectApi {
|
||||
.put(input, asyncCallback);
|
||||
}
|
||||
|
||||
/** Create a new branch */
|
||||
public static void createBranch(Project.NameKey projectName, String ref,
|
||||
String revision, AsyncCallback<BranchInfo> asyncCallback) {
|
||||
BranchInput input = BranchInput.create();
|
||||
input.setRevision(revision);
|
||||
new RestApi("/projects/").id(projectName.get()).view("branches").id(ref)
|
||||
.ifNoneMatch().put(input, asyncCallback);
|
||||
}
|
||||
|
||||
static RestApi config(Project.NameKey name) {
|
||||
return new RestApi("/projects/").id(name.get()).view("config");
|
||||
}
|
||||
@ -53,4 +62,15 @@ public class ProjectApi {
|
||||
|
||||
final native void setCreateEmptyCommit(boolean cc) /*-{ if(cc)this.create_empty_commit=cc; }-*/;
|
||||
}
|
||||
|
||||
private static class BranchInput extends JavaScriptObject {
|
||||
static BranchInput create() {
|
||||
return (BranchInput) createObject();
|
||||
}
|
||||
|
||||
protected BranchInput() {
|
||||
}
|
||||
|
||||
final native void setRevision(String r) /*-{ if(r)this.revision=r; }-*/;
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
package com.google.gerrit.httpd.rpc.project;
|
||||
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
import com.google.gerrit.common.data.AddBranchResult;
|
||||
import com.google.gerrit.common.data.ListBranchesResult;
|
||||
import com.google.gerrit.common.data.ProjectAccess;
|
||||
import com.google.gerrit.common.data.ProjectAdminService;
|
||||
@ -32,7 +31,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
class ProjectAdminServiceImpl implements ProjectAdminService {
|
||||
private final AddBranch.Factory addBranchFactory;
|
||||
private final ChangeProjectAccess.Factory changeProjectAccessFactory;
|
||||
private final ReviewProjectAccess.Factory reviewProjectAccessFactory;
|
||||
private final ChangeProjectSettings.Factory changeProjectSettingsFactory;
|
||||
@ -43,8 +41,7 @@ class ProjectAdminServiceImpl implements ProjectAdminService {
|
||||
private final ProjectDetailFactory.Factory projectDetailFactory;
|
||||
|
||||
@Inject
|
||||
ProjectAdminServiceImpl(final AddBranch.Factory addBranchFactory,
|
||||
final ChangeProjectAccess.Factory changeProjectAccessFactory,
|
||||
ProjectAdminServiceImpl(final ChangeProjectAccess.Factory changeProjectAccessFactory,
|
||||
final ReviewProjectAccess.Factory reviewProjectAccessFactory,
|
||||
final ChangeProjectSettings.Factory changeProjectSettingsFactory,
|
||||
final DeleteBranches.Factory deleteBranchesFactory,
|
||||
@ -52,7 +49,6 @@ class ProjectAdminServiceImpl implements ProjectAdminService {
|
||||
final VisibleProjectDetails.Factory visibleProjectDetailsFactory,
|
||||
final ProjectAccessFactory.Factory projectAccessFactory,
|
||||
final ProjectDetailFactory.Factory projectDetailFactory) {
|
||||
this.addBranchFactory = addBranchFactory;
|
||||
this.changeProjectAccessFactory = changeProjectAccessFactory;
|
||||
this.reviewProjectAccessFactory = reviewProjectAccessFactory;
|
||||
this.changeProjectSettingsFactory = changeProjectSettingsFactory;
|
||||
@ -119,12 +115,4 @@ class ProjectAdminServiceImpl implements ProjectAdminService {
|
||||
final AsyncCallback<Set<Branch.NameKey>> callback) {
|
||||
deleteBranchesFactory.create(projectName, toRemove).to(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBranch(final Project.NameKey projectName,
|
||||
final String branchName, final String startingRevision,
|
||||
final AsyncCallback<AddBranchResult> callback) {
|
||||
addBranchFactory.create(projectName, branchName, startingRevision).to(
|
||||
callback);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ public class ProjectModule extends RpcServletModule {
|
||||
install(new FactoryModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
factory(AddBranch.Factory.class);
|
||||
factory(ChangeProjectAccess.Factory.class);
|
||||
factory(ReviewProjectAccess.Factory.class);
|
||||
factory(ChangeProjectSettings.Factory.class);
|
||||
|
@ -15,6 +15,7 @@
|
||||
package com.google.gerrit.server.project;
|
||||
|
||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||
import com.google.gerrit.extensions.restapi.AcceptsCreate;
|
||||
import com.google.gerrit.extensions.restapi.ChildCollection;
|
||||
import com.google.gerrit.extensions.restapi.IdString;
|
||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||
@ -29,15 +30,18 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class BranchesCollection implements
|
||||
ChildCollection<ProjectResource, BranchResource> {
|
||||
ChildCollection<ProjectResource, BranchResource>,
|
||||
AcceptsCreate<ProjectResource> {
|
||||
private final DynamicMap<RestView<BranchResource>> views;
|
||||
private final Provider<ListBranches> list;
|
||||
private final CreateBranch.Factory createBranchFactory;
|
||||
|
||||
@Inject
|
||||
BranchesCollection(DynamicMap<RestView<BranchResource>> views,
|
||||
Provider<ListBranches> list) {
|
||||
Provider<ListBranches> list, CreateBranch.Factory createBranchFactory) {
|
||||
this.views = views;
|
||||
this.list = list;
|
||||
this.createBranchFactory = createBranchFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -66,4 +70,10 @@ public class BranchesCollection implements
|
||||
public DynamicMap<RestView<BranchResource>> views() {
|
||||
return views;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public CreateBranch create(ProjectResource parent, IdString name) {
|
||||
return createBranchFactory.create(name.get());
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 The Android Open Source Project
|
||||
// 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.
|
||||
@ -12,26 +12,28 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.httpd.rpc.project;
|
||||
package com.google.gerrit.server.project;
|
||||
|
||||
import com.google.gerrit.common.ChangeHooks;
|
||||
import com.google.gerrit.common.data.AddBranchResult;
|
||||
import com.google.gerrit.common.errors.InvalidRevisionException;
|
||||
import com.google.gerrit.httpd.rpc.Handler;
|
||||
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||
import com.google.gerrit.extensions.restapi.DefaultInput;
|
||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||
import com.google.gerrit.extensions.restapi.RestModifyView;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
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.NoSuchProjectException;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gerrit.server.project.RefControl;
|
||||
import com.google.gerrit.server.project.CreateBranch.Input;
|
||||
import com.google.gerrit.server.project.ListBranches.BranchInfo;
|
||||
import com.google.gerrit.server.util.MagicBranch;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||
import org.eclipse.jgit.errors.MissingObjectException;
|
||||
import org.eclipse.jgit.errors.RevisionSyntaxException;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
@ -45,101 +47,92 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class AddBranch extends Handler<AddBranchResult> {
|
||||
private static final Logger log = LoggerFactory.getLogger(AddBranch.class);
|
||||
public class CreateBranch implements RestModifyView<ProjectResource, Input> {
|
||||
private static final Logger log = LoggerFactory.getLogger(CreateBranch.class);
|
||||
|
||||
interface Factory {
|
||||
AddBranch create(@Assisted Project.NameKey projectName,
|
||||
@Assisted("branchName") String branchName,
|
||||
@Assisted("startingRevision") String startingRevision);
|
||||
static class Input {
|
||||
String ref;
|
||||
|
||||
@DefaultInput
|
||||
String revision;
|
||||
}
|
||||
|
||||
static interface Factory {
|
||||
CreateBranch create(String ref);
|
||||
}
|
||||
|
||||
private final ProjectControl.Factory projectControlFactory;
|
||||
private final ListBranches.Factory listBranchesFactory;
|
||||
private final IdentifiedUser identifiedUser;
|
||||
private final GitRepositoryManager repoManager;
|
||||
private final GitReferenceUpdated referenceUpdated;
|
||||
private final ChangeHooks hooks;
|
||||
|
||||
private final Project.NameKey projectName;
|
||||
private final String branchName;
|
||||
private final String startingRevision;
|
||||
private String ref;
|
||||
|
||||
@Inject
|
||||
AddBranch(final ProjectControl.Factory projectControlFactory,
|
||||
final ListBranches.Factory listBranchesFactory,
|
||||
final IdentifiedUser identifiedUser,
|
||||
final GitRepositoryManager repoManager,
|
||||
GitReferenceUpdated referenceUpdated,
|
||||
final ChangeHooks hooks,
|
||||
|
||||
@Assisted Project.NameKey projectName,
|
||||
@Assisted("branchName") String branchName,
|
||||
@Assisted("startingRevision") String startingRevision) {
|
||||
this.projectControlFactory = projectControlFactory;
|
||||
this.listBranchesFactory = listBranchesFactory;
|
||||
CreateBranch(IdentifiedUser identifiedUser, GitRepositoryManager repoManager,
|
||||
GitReferenceUpdated referenceUpdated, ChangeHooks hooks,
|
||||
@Assisted String ref) {
|
||||
this.identifiedUser = identifiedUser;
|
||||
this.repoManager = repoManager;
|
||||
this.referenceUpdated = referenceUpdated;
|
||||
this.hooks = hooks;
|
||||
|
||||
this.projectName = projectName;
|
||||
this.branchName = branchName;
|
||||
this.startingRevision = startingRevision;
|
||||
this.ref = ref;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddBranchResult call() throws NoSuchProjectException, IOException {
|
||||
final ProjectControl projectControl =
|
||||
projectControlFactory.controlFor(projectName);
|
||||
|
||||
String refname = branchName;
|
||||
while (refname.startsWith("/")) {
|
||||
refname = refname.substring(1);
|
||||
public BranchInfo apply(ProjectResource rsrc, Input input)
|
||||
throws BadRequestException, ResourceConflictException, IOException {
|
||||
if (input == null) {
|
||||
input = new Input();
|
||||
}
|
||||
if (!refname.startsWith(Constants.R_REFS)) {
|
||||
refname = Constants.R_HEADS + refname;
|
||||
if (input.ref != null && !ref.equals(input.ref)) {
|
||||
throw new BadRequestException("ref must match URL");
|
||||
}
|
||||
if (!Repository.isValidRefName(refname)) {
|
||||
return new AddBranchResult(new AddBranchResult.Error(
|
||||
AddBranchResult.Error.Type.INVALID_NAME, refname));
|
||||
if (input.revision == null) {
|
||||
input.revision = Constants.HEAD;
|
||||
}
|
||||
if (MagicBranch.isMagicBranch(refname)) {
|
||||
return new AddBranchResult(
|
||||
new AddBranchResult.Error(
|
||||
AddBranchResult.Error.Type.BRANCH_CREATION_NOT_ALLOWED_UNDER_REFNAME_PREFIX,
|
||||
MagicBranch.getMagicRefNamePrefix(refname)));
|
||||
while (ref.startsWith("/")) {
|
||||
ref = ref.substring(1);
|
||||
}
|
||||
if (!ref.startsWith(Constants.R_REFS)) {
|
||||
ref = Constants.R_HEADS + ref;
|
||||
}
|
||||
if (!Repository.isValidRefName(ref)) {
|
||||
throw new BadRequestException("invalid branch name \"" + ref + "\"");
|
||||
}
|
||||
if (MagicBranch.isMagicBranch(ref)) {
|
||||
throw new BadRequestException("not allowed to create branches under \""
|
||||
+ MagicBranch.getMagicRefNamePrefix(ref) + "\"");
|
||||
}
|
||||
|
||||
final Branch.NameKey name = new Branch.NameKey(projectName, refname);
|
||||
final RefControl refControl = projectControl.controlForRef(name);
|
||||
final Repository repo = repoManager.openRepository(projectName);
|
||||
final Branch.NameKey name = new Branch.NameKey(rsrc.getNameKey(), ref);
|
||||
final RefControl refControl = rsrc.getControl().controlForRef(name);
|
||||
final Repository repo = repoManager.openRepository(rsrc.getNameKey());
|
||||
try {
|
||||
final ObjectId revid = parseStartingRevision(repo);
|
||||
final ObjectId revid = parseBaseRevision(repo, rsrc.getNameKey(), input.revision);
|
||||
final RevWalk rw = verifyConnected(repo, revid);
|
||||
RevObject object = rw.parseAny(revid);
|
||||
|
||||
if (refname.startsWith(Constants.R_HEADS)) {
|
||||
if (ref.startsWith(Constants.R_HEADS)) {
|
||||
// Ensure that what we start the branch from is a commit. If we
|
||||
// were given a tag, deference to the commit instead.
|
||||
//
|
||||
try {
|
||||
object = rw.parseCommit(object);
|
||||
} catch (IncorrectObjectTypeException notCommit) {
|
||||
throw new IllegalStateException(startingRevision + " not a commit");
|
||||
throw new BadRequestException("\"" + input.revision + "\" not a commit");
|
||||
}
|
||||
}
|
||||
|
||||
if (!refControl.canCreate(rw, object)) {
|
||||
throw new IllegalStateException("Cannot create " + refname);
|
||||
throw new IllegalStateException("Cannot create \"" + ref + "\"");
|
||||
}
|
||||
|
||||
try {
|
||||
final RefUpdate u = repo.updateRef(refname);
|
||||
final RefUpdate u = repo.updateRef(ref);
|
||||
u.setExpectedOldObjectId(ObjectId.zeroId());
|
||||
u.setNewObjectId(object.copy());
|
||||
u.setRefLogIdent(identifiedUser.newRefLogIdent());
|
||||
u.setRefLogMessage("created via web from " + startingRevision, false);
|
||||
u.setRefLogMessage("created via REST from " + input.revision, false);
|
||||
final RefUpdate.Result result = u.update(rw);
|
||||
switch (result) {
|
||||
case FAST_FORWARD:
|
||||
@ -149,15 +142,16 @@ class AddBranch extends Handler<AddBranchResult> {
|
||||
hooks.doRefUpdatedHook(name, u, identifiedUser.getAccount());
|
||||
break;
|
||||
case LOCK_FAILURE:
|
||||
if (repo.getRef(refname) != null) {
|
||||
return new AddBranchResult(new AddBranchResult.Error(
|
||||
AddBranchResult.Error.Type.BRANCH_ALREADY_EXISTS, refname));
|
||||
if (repo.getRef(ref) != null) {
|
||||
throw new ResourceConflictException("branch \"" + ref
|
||||
+ "\" already exists");
|
||||
}
|
||||
String refPrefix = getRefPrefix(refname);
|
||||
String refPrefix = getRefPrefix(ref);
|
||||
while (!Constants.R_HEADS.equals(refPrefix)) {
|
||||
if (repo.getRef(refPrefix) != null) {
|
||||
return new AddBranchResult(new AddBranchResult.Error(
|
||||
AddBranchResult.Error.Type.BRANCH_CREATION_CONFLICT, refPrefix));
|
||||
throw new ResourceConflictException("Cannot create branch \""
|
||||
+ ref + "\" since it conflicts with branch \"" + refPrefix
|
||||
+ "\".");
|
||||
}
|
||||
refPrefix = getRefPrefix(refPrefix);
|
||||
}
|
||||
@ -165,18 +159,21 @@ class AddBranch extends Handler<AddBranchResult> {
|
||||
throw new IOException(result.name());
|
||||
}
|
||||
}
|
||||
|
||||
BranchInfo b = new BranchInfo();
|
||||
b.ref = ref;
|
||||
b.revision = revid.getName();
|
||||
b.setCanDelete(refControl.canDelete());
|
||||
return b;
|
||||
} catch (IOException err) {
|
||||
log.error("Cannot create branch " + name, err);
|
||||
log.error("Cannot create branch \"" + name + "\"", err);
|
||||
throw err;
|
||||
}
|
||||
} catch (InvalidRevisionException e) {
|
||||
return new AddBranchResult(new AddBranchResult.Error(
|
||||
AddBranchResult.Error.Type.INVALID_REVISION));
|
||||
throw new BadRequestException("invalid revision \"" + input.revision + "\"");
|
||||
} finally {
|
||||
repo.close();
|
||||
}
|
||||
|
||||
return new AddBranchResult(listBranchesFactory.create(projectName).call());
|
||||
}
|
||||
|
||||
private static String getRefPrefix(final String refName) {
|
||||
@ -187,17 +184,21 @@ class AddBranch extends Handler<AddBranchResult> {
|
||||
return Constants.R_HEADS;
|
||||
}
|
||||
|
||||
private ObjectId parseStartingRevision(final Repository repo)
|
||||
private ObjectId parseBaseRevision(Repository repo,
|
||||
Project.NameKey projectName, String baseRevision)
|
||||
throws InvalidRevisionException {
|
||||
try {
|
||||
final ObjectId revid = repo.resolve(startingRevision);
|
||||
final ObjectId revid = repo.resolve(baseRevision);
|
||||
if (revid == null) {
|
||||
throw new InvalidRevisionException();
|
||||
}
|
||||
return revid;
|
||||
} catch (IOException err) {
|
||||
log.error("Cannot resolve \"" + startingRevision + "\" in project \""
|
||||
+ projectName + "\"", err);
|
||||
log.error("Cannot resolve \"" + baseRevision + "\" in project \""
|
||||
+ projectName.get() + "\"", err);
|
||||
throw new InvalidRevisionException();
|
||||
} catch (RevisionSyntaxException err) {
|
||||
log.error("Invalid revision syntax \"" + baseRevision + "\"", err);
|
||||
throw new InvalidRevisionException();
|
||||
}
|
||||
}
|
@ -53,7 +53,9 @@ public class Module extends RestApiModule {
|
||||
post(PROJECT_KIND, "gc").to(GarbageCollect.class);
|
||||
|
||||
child(PROJECT_KIND, "branches").to(BranchesCollection.class);
|
||||
put(BRANCH_KIND).to(PutBranch.class);
|
||||
get(BRANCH_KIND).to(GetBranch.class);
|
||||
install(new FactoryModuleBuilder().build(CreateBranch.Factory.class));
|
||||
|
||||
child(PROJECT_KIND, "dashboards").to(DashboardsCollection.class);
|
||||
get(DASHBOARD_KIND).to(GetDashboard.class);
|
||||
|
@ -0,0 +1,29 @@
|
||||
// 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.extensions.restapi.ResourceConflictException;
|
||||
import com.google.gerrit.extensions.restapi.RestModifyView;
|
||||
import com.google.gerrit.server.project.CreateBranch.Input;
|
||||
|
||||
public class PutBranch implements RestModifyView<BranchResource, Input> {
|
||||
|
||||
@Override
|
||||
public Object apply(BranchResource rsrc, Input input)
|
||||
throws ResourceConflictException {
|
||||
throw new ResourceConflictException("Branch \"" + rsrc.getBranchInfo().ref
|
||||
+ "\" already exists");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user