use of org.eclipse.jgit.lib.RefUpdate in project gerrit by GerritCodeReview.
the class CreateBranch method apply.
@Override
public Response<BranchInfo> apply(ProjectResource rsrc, IdString id, BranchInput input) throws BadRequestException, AuthException, ResourceConflictException, IOException, PermissionBackendException, NoSuchProjectException {
String ref = id.get();
if (input == null) {
input = new BranchInput();
}
if (input.ref != null && !ref.equals(input.ref)) {
throw new BadRequestException("ref must match URL");
}
if (input.revision != null) {
input.revision = input.revision.trim();
}
if (Strings.isNullOrEmpty(input.revision)) {
input.revision = Constants.HEAD;
}
while (ref.startsWith("/")) {
ref = ref.substring(1);
}
ref = RefNames.fullName(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) + "\"");
}
if (!isBranchAllowed(ref)) {
throw new BadRequestException("Cannot create a branch with name \"" + ref + "\". Not allowed to create branches under Gerrit internal or tags refs.");
}
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);
RevObject object = rw.parseAny(revid);
if (ref.startsWith(Constants.R_HEADS)) {
// Ensure that what we start the branch from is a commit. If we
// were given a tag, dereference to the commit instead.
//
object = rw.parseCommit(object);
}
createRefControl.checkCreateRef(identifiedUser, repo, name, object);
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, getValidateOptionsAsMultimap(input.validationOptions));
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 + "\".");
}
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);
}
}
use of org.eclipse.jgit.lib.RefUpdate in project gerrit by GerritCodeReview.
the class DeleteRef method createDeleteCommand.
private ReceiveCommand createDeleteCommand(ProjectState projectState, Repository r, String refName) throws IOException, ResourceConflictException, PermissionBackendException {
Ref ref = r.getRefDatabase().exactRef(refName);
ReceiveCommand command;
if (ref == null) {
command = new ReceiveCommand(ObjectId.zeroId(), ObjectId.zeroId(), refName);
command.setResult(Result.REJECTED_OTHER_REASON, "it doesn't exist or you do not have permission to delete it");
return command;
}
command = new ReceiveCommand(ref.getObjectId(), ObjectId.zeroId(), ref.getName());
if (isConfigRef(refName)) {
// Never allow to delete the meta config branch.
command.setResult(Result.REJECTED_OTHER_REASON, "not allowed to delete branch " + refName);
} else {
try {
permissionBackend.currentUser().project(projectState.getNameKey()).ref(refName).check(RefPermission.DELETE);
} catch (AuthException denied) {
command.setResult(Result.REJECTED_OTHER_REASON, "it doesn't exist or you do not have permission to delete it");
}
}
if (!projectState.statePermitsWrite()) {
command.setResult(Result.REJECTED_OTHER_REASON, "project state does not permit write");
}
if (!refName.startsWith(R_TAGS)) {
BranchNameKey branchKey = BranchNameKey.create(projectState.getNameKey(), ref.getName());
if (!queryProvider.get().setLimit(1).byBranchOpen(branchKey).isEmpty()) {
command.setResult(Result.REJECTED_OTHER_REASON, "it has open changes");
}
}
RefUpdate u = r.updateRef(refName);
u.setForceUpdate(true);
u.setExpectedOldObjectId(r.exactRef(refName).getObjectId());
u.setNewObjectId(ObjectId.zeroId());
refDeletionValidator.validateRefOperation(projectState.getName(), identifiedUser.get(), u, /* pushOptions */
ImmutableListMultimap.of());
return command;
}
use of org.eclipse.jgit.lib.RefUpdate in project gerrit by GerritCodeReview.
the class DeleteRef method deleteSingleRef.
/**
* Deletes a single ref from the repository.
*
* @param projectState the {@code ProjectState} of the project containing the target ref.
* @param ref the ref to be deleted.
* @param prefix the prefix of the ref.
*/
public void deleteSingleRef(ProjectState projectState, String ref, @Nullable String prefix) throws IOException, ResourceConflictException, AuthException, PermissionBackendException {
if (prefix != null && !ref.startsWith(R_REFS)) {
ref = prefix + ref;
}
projectState.checkStatePermitsWrite();
permissionBackend.currentUser().project(projectState.getNameKey()).ref(ref).check(RefPermission.DELETE);
try (Repository repository = repoManager.openRepository(projectState.getNameKey())) {
RefUpdate.Result result;
RefUpdate u = repository.updateRef(ref);
u.setExpectedOldObjectId(repository.exactRef(ref).getObjectId());
u.setNewObjectId(ObjectId.zeroId());
u.setForceUpdate(true);
refDeletionValidator.validateRefOperation(projectState.getName(), identifiedUser.get(), u, /* pushOptions */
ImmutableListMultimap.of());
result = u.delete();
switch(result) {
case NEW:
case NO_CHANGE:
case FAST_FORWARD:
case FORCED:
referenceUpdated.fire(projectState.getNameKey(), u, ReceiveCommand.Type.DELETE, identifiedUser.get().state());
break;
case REJECTED_CURRENT_BRANCH:
logger.atFine().log("Cannot delete current branch %s: %s", ref, result.name());
throw new ResourceConflictException("cannot delete current branch");
case LOCK_FAILURE:
throw new LockFailureException(String.format("Cannot delete %s", ref), u);
case IO_FAILURE:
case NOT_ATTEMPTED:
case REJECTED:
case RENAMED:
case REJECTED_MISSING_OBJECT:
case REJECTED_OTHER_REASON:
default:
throw new StorageException(String.format("Cannot delete %s: %s", ref, result.name()));
}
}
}
use of org.eclipse.jgit.lib.RefUpdate in project gerrit by GerritCodeReview.
the class AccountIT method stalenessChecker.
@Test
// Instants
@SuppressWarnings("JdkObsolete")
public void stalenessChecker() throws Exception {
// Newly created account is not stale.
AccountInfo accountInfo = gApi.accounts().create(name("foo")).get();
Account.Id accountId = Account.id(accountInfo._accountId);
assertThat(stalenessChecker.check(accountId).isStale()).isFalse();
// Manually updating the user ref makes the index document stale.
String userRef = RefNames.refsUsers(accountId);
try (Repository repo = repoManager.openRepository(allUsers);
ObjectInserter oi = repo.newObjectInserter();
RevWalk rw = new RevWalk(repo)) {
RevCommit commit = rw.parseCommit(repo.exactRef(userRef).getObjectId());
PersonIdent ident = new PersonIdent(serverIdent.get(), Date.from(TimeUtil.now()));
CommitBuilder cb = new CommitBuilder();
cb.setTreeId(commit.getTree());
cb.setCommitter(ident);
cb.setAuthor(ident);
cb.setMessage(commit.getFullMessage());
ObjectId emptyCommit = oi.insert(cb);
oi.flush();
RefUpdate updateRef = repo.updateRef(userRef);
updateRef.setExpectedOldObjectId(commit.toObjectId());
updateRef.setNewObjectId(emptyCommit);
assertThat(updateRef.forceUpdate()).isEqualTo(RefUpdate.Result.FORCED);
}
assertStaleAccountAndReindex(accountId);
// stale.
try (Repository repo = repoManager.openRepository(allUsers)) {
ExternalIdNotes extIdNotes = ExternalIdNotes.load(allUsers, repo, externalIdFactory, authConfig.isUserNameCaseInsensitiveMigrationMode());
ExternalId.Key key = externalIdKeyFactory.create("foo", "foo");
extIdNotes.insert(externalIdFactory.create(key, accountId));
try (MetaDataUpdate update = metaDataUpdateFactory.create(allUsers)) {
extIdNotes.commit(update);
}
assertStaleAccountAndReindex(accountId);
extIdNotes = ExternalIdNotes.load(allUsers, repo, externalIdFactory, authConfig.isUserNameCaseInsensitiveMigrationMode());
extIdNotes.upsert(externalIdFactory.createWithEmail(key, accountId, "foo@example.com"));
try (MetaDataUpdate update = metaDataUpdateFactory.create(allUsers)) {
extIdNotes.commit(update);
}
assertStaleAccountAndReindex(accountId);
extIdNotes = ExternalIdNotes.load(allUsers, repo, externalIdFactory, authConfig.isUserNameCaseInsensitiveMigrationMode());
extIdNotes.delete(accountId, key);
try (MetaDataUpdate update = metaDataUpdateFactory.create(allUsers)) {
extIdNotes.commit(update);
}
assertStaleAccountAndReindex(accountId);
}
// Manually delete account
try (Repository repo = repoManager.openRepository(allUsers);
RevWalk rw = new RevWalk(repo)) {
RevCommit commit = rw.parseCommit(repo.exactRef(userRef).getObjectId());
RefUpdate updateRef = repo.updateRef(userRef);
updateRef.setExpectedOldObjectId(commit.toObjectId());
updateRef.setNewObjectId(ObjectId.zeroId());
updateRef.setForceUpdate(true);
assertThat(updateRef.delete()).isEqualTo(RefUpdate.Result.FORCED);
}
assertStaleAccountAndReindex(accountId);
}
use of org.eclipse.jgit.lib.RefUpdate in project gerrit by GerritCodeReview.
the class AccountIT method clearPublicKeyStore.
@After
public void clearPublicKeyStore() throws Exception {
try (Repository repo = repoManager.openRepository(allUsers)) {
Ref ref = repo.exactRef(REFS_GPG_KEYS);
if (ref != null) {
RefUpdate ru = repo.updateRef(REFS_GPG_KEYS);
ru.setForceUpdate(true);
assertThat(ru.delete()).isEqualTo(RefUpdate.Result.FORCED);
}
}
}
Aggregations