Search in sources :

Example 81 with RefUpdate

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);
    }
}
Also used : BranchInfo(com.google.gerrit.extensions.api.projects.BranchInfo) ObjectId(org.eclipse.jgit.lib.ObjectId) RevObject(org.eclipse.jgit.revwalk.RevObject) IdString(com.google.gerrit.extensions.restapi.IdString) IOException(java.io.IOException) RefUtil(com.google.gerrit.server.project.RefUtil) RevWalk(org.eclipse.jgit.revwalk.RevWalk) LockFailureException(com.google.gerrit.git.LockFailureException) Repository(org.eclipse.jgit.lib.Repository) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) BranchNameKey(com.google.gerrit.entities.BranchNameKey) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) BranchInput(com.google.gerrit.extensions.api.projects.BranchInput) RefUpdate(org.eclipse.jgit.lib.RefUpdate)

Example 82 with RefUpdate

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;
}
Also used : ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) Ref(org.eclipse.jgit.lib.Ref) RefNames.isConfigRef(com.google.gerrit.entities.RefNames.isConfigRef) BranchNameKey(com.google.gerrit.entities.BranchNameKey) AuthException(com.google.gerrit.extensions.restapi.AuthException) RefUpdate(org.eclipse.jgit.lib.RefUpdate) BatchRefUpdate(org.eclipse.jgit.lib.BatchRefUpdate)

Example 83 with RefUpdate

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()));
        }
    }
}
Also used : Repository(org.eclipse.jgit.lib.Repository) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) StorageException(com.google.gerrit.exceptions.StorageException) LockFailureException(com.google.gerrit.git.LockFailureException) RefUpdate(org.eclipse.jgit.lib.RefUpdate) BatchRefUpdate(org.eclipse.jgit.lib.BatchRefUpdate)

Example 84 with RefUpdate

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);
}
Also used : TestAccount(com.google.gerrit.acceptance.TestAccount) Account(com.google.gerrit.entities.Account) ObjectId(org.eclipse.jgit.lib.ObjectId) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) PublicKeyStore.keyToString(com.google.gerrit.gpg.PublicKeyStore.keyToString) RevWalk(org.eclipse.jgit.revwalk.RevWalk) TestRepository(org.eclipse.jgit.junit.TestRepository) Repository(org.eclipse.jgit.lib.Repository) InMemoryRepository(org.eclipse.jgit.internal.storage.dfs.InMemoryRepository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PersonIdent(org.eclipse.jgit.lib.PersonIdent) ExternalIdNotes(com.google.gerrit.server.account.externalids.ExternalIdNotes) AccountInfo(com.google.gerrit.extensions.common.AccountInfo) RevCommit(org.eclipse.jgit.revwalk.RevCommit) RefUpdate(org.eclipse.jgit.lib.RefUpdate) RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate) MetaDataUpdate(com.google.gerrit.server.git.meta.MetaDataUpdate) AbstractDaemonTest(com.google.gerrit.acceptance.AbstractDaemonTest) Test(org.junit.Test)

Example 85 with RefUpdate

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);
        }
    }
}
Also used : TestRepository(org.eclipse.jgit.junit.TestRepository) Repository(org.eclipse.jgit.lib.Repository) InMemoryRepository(org.eclipse.jgit.internal.storage.dfs.InMemoryRepository) GitUtil.deleteRef(com.google.gerrit.acceptance.GitUtil.deleteRef) Ref(org.eclipse.jgit.lib.Ref) RefUpdate(org.eclipse.jgit.lib.RefUpdate) RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate) After(org.junit.After)

Aggregations

RefUpdate (org.eclipse.jgit.lib.RefUpdate)110 Repository (org.eclipse.jgit.lib.Repository)51 ObjectId (org.eclipse.jgit.lib.ObjectId)45 IOException (java.io.IOException)34 Test (org.junit.Test)32 AbstractDaemonTest (com.google.gerrit.acceptance.AbstractDaemonTest)27 TestRepository (org.eclipse.jgit.junit.TestRepository)26 ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)24 RevWalk (org.eclipse.jgit.revwalk.RevWalk)23 Result (org.eclipse.jgit.lib.RefUpdate.Result)22 RevCommit (org.eclipse.jgit.revwalk.RevCommit)20 CommitBuilder (org.eclipse.jgit.lib.CommitBuilder)18 Ref (org.eclipse.jgit.lib.Ref)17 RemoteRefUpdate (org.eclipse.jgit.transport.RemoteRefUpdate)17 PushOneCommit (com.google.gerrit.acceptance.PushOneCommit)15 BatchRefUpdate (org.eclipse.jgit.lib.BatchRefUpdate)14 InMemoryRepository (org.eclipse.jgit.internal.storage.dfs.InMemoryRepository)12 LockFailureException (com.google.gerrit.git.LockFailureException)10 PersonIdent (org.eclipse.jgit.lib.PersonIdent)9 DirCache (org.eclipse.jgit.dircache.DirCache)8