Merge changes I181742e8,If3e0a715,I9653f133,I230b7bf6
* changes: CreateBranch: Test that refs/meta/config branch can be created CreateBranch: Remove unreachable catch block for IncorrectObjectTypeException CreateBranch: Remove unneeded usages of final CreateBranch: Remove unneeded try-catch block
This commit is contained in:
@@ -17,7 +17,6 @@ package com.google.gerrit.server.restapi.project;
|
||||
import static com.google.gerrit.entities.RefNames.isConfigRef;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.gerrit.entities.BranchNameKey;
|
||||
import com.google.gerrit.entities.RefNames;
|
||||
import com.google.gerrit.extensions.api.projects.BranchInfo;
|
||||
@@ -46,7 +45,6 @@ import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.RefUpdate;
|
||||
@@ -58,8 +56,6 @@ import org.eclipse.jgit.transport.ReceiveCommand;
|
||||
@Singleton
|
||||
public class CreateBranch
|
||||
implements RestCollectionCreateView<ProjectResource, BranchResource, BranchInput> {
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
private final Provider<IdentifiedUser> identifiedUser;
|
||||
private final PermissionBackend permissionBackend;
|
||||
private final GitRepositoryManager repoManager;
|
||||
@@ -114,7 +110,7 @@ public class CreateBranch
|
||||
+ "\"");
|
||||
}
|
||||
|
||||
final BranchNameKey name = BranchNameKey.create(rsrc.getNameKey(), ref);
|
||||
BranchNameKey name = BranchNameKey.create(rsrc.getNameKey(), ref);
|
||||
try (Repository repo = repoManager.openRepository(rsrc.getNameKey())) {
|
||||
ObjectId revid = RefUtil.parseBaseRevision(repo, rsrc.getNameKey(), input.revision);
|
||||
RevWalk rw = RefUtil.verifyConnected(repo, revid);
|
||||
@@ -122,80 +118,71 @@ public class CreateBranch
|
||||
|
||||
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.
|
||||
// were given a tag, dereference to the commit instead.
|
||||
//
|
||||
try {
|
||||
object = rw.parseCommit(object);
|
||||
} catch (IncorrectObjectTypeException notCommit) {
|
||||
throw new BadRequestException("\"" + input.revision + "\" not a commit", notCommit);
|
||||
}
|
||||
object = rw.parseCommit(object);
|
||||
}
|
||||
|
||||
createRefControl.checkCreateRef(identifiedUser, repo, name, object);
|
||||
|
||||
try {
|
||||
final RefUpdate u = repo.updateRef(ref);
|
||||
u.setExpectedOldObjectId(ObjectId.zeroId());
|
||||
u.setNewObjectId(object.copy());
|
||||
u.setRefLogIdent(identifiedUser.get().newRefLogIdent());
|
||||
u.setRefLogMessage("created via REST from " + input.revision, false);
|
||||
refCreationValidator.validateRefOperation(rsrc.getName(), identifiedUser.get(), u);
|
||||
final RefUpdate.Result result = u.update(rw);
|
||||
switch (result) {
|
||||
case FAST_FORWARD:
|
||||
case NEW:
|
||||
case NO_CHANGE:
|
||||
referenceUpdated.fire(
|
||||
name.project(), u, ReceiveCommand.Type.CREATE, identifiedUser.get().state());
|
||||
break;
|
||||
case LOCK_FAILURE:
|
||||
if (repo.getRefDatabase().exactRef(ref) != null) {
|
||||
throw new ResourceConflictException("branch \"" + ref + "\" already exists");
|
||||
RefUpdate u = repo.updateRef(ref);
|
||||
u.setExpectedOldObjectId(ObjectId.zeroId());
|
||||
u.setNewObjectId(object.copy());
|
||||
u.setRefLogIdent(identifiedUser.get().newRefLogIdent());
|
||||
u.setRefLogMessage("created via REST from " + input.revision, false);
|
||||
refCreationValidator.validateRefOperation(rsrc.getName(), identifiedUser.get(), u);
|
||||
RefUpdate.Result result = u.update(rw);
|
||||
switch (result) {
|
||||
case FAST_FORWARD:
|
||||
case NEW:
|
||||
case NO_CHANGE:
|
||||
referenceUpdated.fire(
|
||||
name.project(), u, ReceiveCommand.Type.CREATE, identifiedUser.get().state());
|
||||
break;
|
||||
case LOCK_FAILURE:
|
||||
if (repo.getRefDatabase().exactRef(ref) != null) {
|
||||
throw new ResourceConflictException("branch \"" + ref + "\" already exists");
|
||||
}
|
||||
String refPrefix = RefUtil.getRefPrefix(ref);
|
||||
while (!Constants.R_HEADS.equals(refPrefix)) {
|
||||
if (repo.getRefDatabase().exactRef(refPrefix) != null) {
|
||||
throw new ResourceConflictException(
|
||||
"Cannot create branch \""
|
||||
+ ref
|
||||
+ "\" since it conflicts with branch \""
|
||||
+ refPrefix
|
||||
+ "\".");
|
||||
}
|
||||
String refPrefix = RefUtil.getRefPrefix(ref);
|
||||
while (!Constants.R_HEADS.equals(refPrefix)) {
|
||||
if (repo.getRefDatabase().exactRef(refPrefix) != null) {
|
||||
throw new ResourceConflictException(
|
||||
"Cannot create branch \""
|
||||
+ ref
|
||||
+ "\" since it conflicts with branch \""
|
||||
+ refPrefix
|
||||
+ "\".");
|
||||
}
|
||||
refPrefix = RefUtil.getRefPrefix(refPrefix);
|
||||
}
|
||||
throw new LockFailureException(String.format("Failed to create %s", ref), u);
|
||||
case FORCED:
|
||||
case IO_FAILURE:
|
||||
case NOT_ATTEMPTED:
|
||||
case REJECTED:
|
||||
case REJECTED_CURRENT_BRANCH:
|
||||
case RENAMED:
|
||||
case REJECTED_MISSING_OBJECT:
|
||||
case REJECTED_OTHER_REASON:
|
||||
default:
|
||||
throw new IOException(String.format("Failed to create %s: %s", ref, result.name()));
|
||||
}
|
||||
|
||||
BranchInfo info = new BranchInfo();
|
||||
info.ref = ref;
|
||||
info.revision = revid.getName();
|
||||
|
||||
if (isConfigRef(name.branch())) {
|
||||
// Never allow to delete the meta config branch.
|
||||
info.canDelete = null;
|
||||
} else {
|
||||
info.canDelete =
|
||||
permissionBackend.currentUser().ref(name).testOrFalse(RefPermission.DELETE)
|
||||
&& rsrc.getProjectState().statePermitsWrite()
|
||||
? true
|
||||
: null;
|
||||
}
|
||||
return Response.created(info);
|
||||
} catch (IOException err) {
|
||||
logger.atSevere().withCause(err).log("Cannot create branch \"%s\"", name);
|
||||
throw err;
|
||||
refPrefix = RefUtil.getRefPrefix(refPrefix);
|
||||
}
|
||||
throw new LockFailureException(String.format("Failed to create %s", ref), u);
|
||||
case FORCED:
|
||||
case IO_FAILURE:
|
||||
case NOT_ATTEMPTED:
|
||||
case REJECTED:
|
||||
case REJECTED_CURRENT_BRANCH:
|
||||
case RENAMED:
|
||||
case REJECTED_MISSING_OBJECT:
|
||||
case REJECTED_OTHER_REASON:
|
||||
default:
|
||||
throw new IOException(String.format("Failed to create %s: %s", ref, result.name()));
|
||||
}
|
||||
|
||||
BranchInfo info = new BranchInfo();
|
||||
info.ref = ref;
|
||||
info.revision = revid.getName();
|
||||
|
||||
if (isConfigRef(name.branch())) {
|
||||
// Never allow to delete the meta config branch.
|
||||
info.canDelete = null;
|
||||
} else {
|
||||
info.canDelete =
|
||||
permissionBackend.currentUser().ref(name).testOrFalse(RefPermission.DELETE)
|
||||
&& rsrc.getProjectState().statePermitsWrite()
|
||||
? true
|
||||
: null;
|
||||
}
|
||||
return Response.created(info);
|
||||
} catch (RefUtil.InvalidRevisionException e) {
|
||||
throw new BadRequestException("invalid revision \"" + input.revision + "\"", e);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ import com.google.gerrit.server.validators.ValidationException;
|
||||
import com.google.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.eclipse.jgit.junit.TestRepository;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.RefUpdate;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
@@ -188,6 +189,23 @@ public class CreateBranchIT extends AbstractDaemonTest {
|
||||
assertCreateSucceeds(BranchNameKey.create(project, metaRef));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createMetaConfigBranch() throws Exception {
|
||||
// Since the refs/meta/config branch exists by default, we must delete it before we can test
|
||||
// creating it. Since deleting the refs/meta/config branch is not allowed through the API, we
|
||||
// delete it directly in the remote repository.
|
||||
try (TestRepository<Repository> repo =
|
||||
new TestRepository<>(repoManager.openRepository(project))) {
|
||||
repo.delete(RefNames.REFS_CONFIG);
|
||||
}
|
||||
|
||||
// Create refs/meta/config branch.
|
||||
BranchInfo created =
|
||||
branch(BranchNameKey.create(project, RefNames.REFS_CONFIG)).create(new BranchInput()).get();
|
||||
assertThat(created.ref).isEqualTo(RefNames.REFS_CONFIG);
|
||||
assertThat(created.canDelete).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createUserBranch_Conflict() throws Exception {
|
||||
projectOperations
|
||||
|
||||
Reference in New Issue
Block a user