Search in sources :

Example 31 with BranchNameKey

use of com.google.gerrit.entities.BranchNameKey in project gerrit by GerritCodeReview.

the class AbstractQueryChangesTest method testByCommitsOnBranchNotMerged.

private void testByCommitsOnBranchNotMerged(TestRepository<Repo> repo, Collection<ObjectId> extra) throws Exception {
    int n = 10;
    List<String> shas = new ArrayList<>(n + extra.size());
    extra.forEach(i -> shas.add(i.name()));
    List<Integer> expectedIds = new ArrayList<>(n);
    BranchNameKey dest = null;
    for (int i = 0; i < n; i++) {
        ChangeInserter ins = newChange(repo);
        insert(repo, ins);
        if (dest == null) {
            dest = ins.getChange().getDest();
        }
        shas.add(ins.getCommitId().name());
        expectedIds.add(ins.getChange().getId().get());
    }
    for (int i = 1; i <= 11; i++) {
        Iterable<ChangeData> cds = queryProvider.get().byCommitsOnBranchNotMerged(repo.getRepository(), dest, shas, i);
        Iterable<Integer> ids = FluentIterable.from(cds).transform(in -> in.getId().get());
        String name = "limit " + i;
        assertWithMessage(name).that(ids).hasSize(n);
        assertWithMessage(name).that(ids).containsExactlyElementsIn(expectedIds);
    }
}
Also used : BranchNameKey(com.google.gerrit.entities.BranchNameKey) ArrayList(java.util.ArrayList) ChangeInserter(com.google.gerrit.server.change.ChangeInserter)

Example 32 with BranchNameKey

use of com.google.gerrit.entities.BranchNameKey in project gerrit by GerritCodeReview.

the class DestinationList method asText.

String asText(String label) {
    Set<BranchNameKey> dests = destinations.get(label);
    if (dests == null) {
        return null;
    }
    List<Row> rows = Lists.newArrayListWithCapacity(dests.size());
    for (BranchNameKey dest : sort(dests)) {
        rows.add(new Row(dest.branch(), dest.project().get()));
    }
    return asText("Ref", "Project", rows);
}
Also used : BranchNameKey(com.google.gerrit.entities.BranchNameKey)

Example 33 with BranchNameKey

use of com.google.gerrit.entities.BranchNameKey in project gerrit by GerritCodeReview.

the class CreateMergePatchSet method apply.

// TODO(issue-15517): Fix the JdkObsolete issue with Date once JGit's PersonIdent class supports
// Instants
@SuppressWarnings("JdkObsolete")
@Override
public Response<ChangeInfo> apply(ChangeResource rsrc, MergePatchSetInput in) throws IOException, RestApiException, UpdateException, PermissionBackendException {
    // Not allowed to create a new patch set if the current patch set is locked.
    psUtil.checkPatchSetNotLocked(rsrc.getNotes());
    rsrc.permissions().check(ChangePermission.ADD_PATCH_SET);
    if (in.author != null) {
        permissionBackend.currentUser().project(rsrc.getProject()).ref(rsrc.getChange().getDest().branch()).check(RefPermission.FORGE_AUTHOR);
    }
    ProjectState projectState = projectCache.get(rsrc.getProject()).orElseThrow(illegalState(rsrc.getProject()));
    projectState.checkStatePermitsWrite();
    MergeInput merge = in.merge;
    if (merge == null || Strings.isNullOrEmpty(merge.source)) {
        throw new BadRequestException("merge.source must be non-empty");
    }
    if (in.author != null && (Strings.isNullOrEmpty(in.author.email) || Strings.isNullOrEmpty(in.author.name))) {
        throw new BadRequestException("Author must specify name and email");
    }
    in.baseChange = Strings.nullToEmpty(in.baseChange).trim();
    PatchSet ps = psUtil.current(rsrc.getNotes());
    Change change = rsrc.getChange();
    Project.NameKey project = change.getProject();
    BranchNameKey dest = change.getDest();
    try (Repository git = gitManager.openRepository(project);
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        CodeReviewRevWalk rw = CodeReviewCommit.newRevWalk(reader)) {
        RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, merge.source);
        if (!commits.canRead(projectState, git, sourceCommit)) {
            throw new ResourceNotFoundException("cannot find source commit: " + merge.source + " to merge.");
        }
        RevCommit currentPsCommit;
        List<String> groups = null;
        if (!in.inheritParent && !in.baseChange.isEmpty()) {
            PatchSet basePS = findBasePatchSet(in.baseChange);
            currentPsCommit = rw.parseCommit(basePS.commitId());
            groups = basePS.groups();
        } else {
            currentPsCommit = rw.parseCommit(ps.commitId());
        }
        Instant now = TimeUtil.now();
        IdentifiedUser me = user.get().asIdentifiedUser();
        PersonIdent author = in.author == null ? me.newCommitterIdent(now, serverTimeZone) : new PersonIdent(in.author.name, in.author.email, Date.from(now), serverTimeZone);
        CodeReviewCommit newCommit = createMergeCommit(in, projectState, dest, git, oi, rw, currentPsCommit, sourceCommit, author, ObjectId.fromString(change.getKey().get().substring(1)));
        oi.flush();
        PatchSet.Id nextPsId = ChangeUtil.nextPatchSetId(ps.id());
        PatchSetInserter psInserter = patchSetInserterFactory.create(rsrc.getNotes(), nextPsId, newCommit);
        try (BatchUpdate bu = updateFactory.create(project, me, now)) {
            bu.setRepository(git, rw, oi);
            bu.setNotify(NotifyResolver.Result.none());
            psInserter.setMessage(messageForChange(nextPsId, newCommit)).setWorkInProgress(!newCommit.getFilesWithGitConflicts().isEmpty()).setCheckAddPatchSetPermission(false);
            if (groups != null) {
                psInserter.setGroups(groups);
            }
            bu.addOp(rsrc.getId(), psInserter);
            bu.execute();
        }
        ChangeJson json = jsonFactory.create(ListChangesOption.CURRENT_REVISION);
        ChangeInfo changeInfo = json.format(psInserter.getChange());
        changeInfo.containsGitConflicts = !newCommit.getFilesWithGitConflicts().isEmpty() ? true : null;
        return Response.ok(changeInfo);
    } catch (InvalidMergeStrategyException | MergeWithConflictsNotSupportedException e) {
        throw new BadRequestException(e.getMessage());
    }
}
Also used : MergeInput(com.google.gerrit.extensions.common.MergeInput) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) BranchNameKey(com.google.gerrit.entities.BranchNameKey) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ObjectReader(org.eclipse.jgit.lib.ObjectReader) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) RevCommit(org.eclipse.jgit.revwalk.RevCommit) ChangeJson(com.google.gerrit.server.change.ChangeJson) ChangeInfo(com.google.gerrit.extensions.common.ChangeInfo) Instant(java.time.Instant) CodeReviewRevWalk(com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk) PatchSet(com.google.gerrit.entities.PatchSet) Change(com.google.gerrit.entities.Change) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit) Project(com.google.gerrit.entities.Project) Repository(org.eclipse.jgit.lib.Repository) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) PatchSetInserter(com.google.gerrit.server.change.PatchSetInserter) InvalidMergeStrategyException(com.google.gerrit.exceptions.InvalidMergeStrategyException) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) MergeWithConflictsNotSupportedException(com.google.gerrit.exceptions.MergeWithConflictsNotSupportedException) ProjectState(com.google.gerrit.server.project.ProjectState)

Example 34 with BranchNameKey

use of com.google.gerrit.entities.BranchNameKey in project gerrit by GerritCodeReview.

the class CherryPickChange method createNewChange.

private Change.Id createNewChange(BatchUpdate bu, CodeReviewCommit cherryPickCommit, String refName, String topic, Project.NameKey project, @Nullable Change sourceChange, @Nullable ObjectId sourceCommit, CherryPickInput input, @Nullable Change.Id revertOf, @Nullable Change.Id idForNewChange, @Nullable Boolean workInProgress) throws IOException, InvalidChangeOperationException {
    Change.Id changeId = idForNewChange != null ? idForNewChange : Change.id(seq.nextChangeId());
    ChangeInserter ins = changeInserterFactory.create(changeId, cherryPickCommit, refName);
    ins.setRevertOf(revertOf);
    if (workInProgress != null) {
        ins.setWorkInProgress(workInProgress);
    } else {
        ins.setWorkInProgress((sourceChange != null && sourceChange.isWorkInProgress()) || !cherryPickCommit.getFilesWithGitConflicts().isEmpty());
    }
    ins.setValidationOptions(getValidateOptionsAsMultimap(input.validationOptions));
    BranchNameKey sourceBranch = sourceChange == null ? null : sourceChange.getDest();
    PatchSet.Id sourcePatchSetId = sourceChange == null ? null : sourceChange.currentPatchSetId();
    ins.setMessage(revertOf == null ? messageForDestinationChange(ins.getPatchSetId(), sourceBranch, sourceCommit, cherryPickCommit) : // For revert commits, the message should not include
    "Uploaded patch set 1.").setTopic(topic).setCherryPickOf(sourcePatchSetId);
    if (input.keepReviewers && sourceChange != null) {
        ReviewerSet reviewerSet = approvalsUtil.getReviewers(changeNotesFactory.createChecked(sourceChange));
        Set<Account.Id> reviewers = new HashSet<>(reviewerSet.byState(ReviewerStateInternal.REVIEWER));
        reviewers.add(sourceChange.getOwner());
        reviewers.remove(user.get().getAccountId());
        Set<Account.Id> ccs = new HashSet<>(reviewerSet.byState(ReviewerStateInternal.CC));
        ccs.remove(user.get().getAccountId());
        ins.setReviewersAndCcs(reviewers, ccs);
    }
    // If there is a base, and the base is not merged, the groups will be overridden by the base's
    // groups.
    ins.setGroups(GroupCollector.getDefaultGroups(cherryPickCommit.getId()));
    if (input.base != null) {
        List<ChangeData> changes = queryProvider.get().setLimit(2).byBranchCommitOpen(project.get(), refName, input.base);
        if (changes.size() > 1) {
            throw new InvalidChangeOperationException("Several changes with key " + input.base + " reside on the same branch. " + "Cannot cherry-pick on target branch.");
        }
        if (changes.size() == 1) {
            Change change = changes.get(0).change();
            ins.setGroups(changeNotesFactory.createChecked(change).getCurrentPatchSet().groups());
        }
    }
    bu.insertChange(ins);
    return changeId;
}
Also used : InvalidChangeOperationException(com.google.gerrit.server.project.InvalidChangeOperationException) PatchSet(com.google.gerrit.entities.PatchSet) Change(com.google.gerrit.entities.Change) ChangeData(com.google.gerrit.server.query.change.ChangeData) BranchNameKey(com.google.gerrit.entities.BranchNameKey) ReviewerSet(com.google.gerrit.server.ReviewerSet) ChangeInserter(com.google.gerrit.server.change.ChangeInserter) ObjectId(org.eclipse.jgit.lib.ObjectId) HashSet(java.util.HashSet)

Example 35 with BranchNameKey

use of com.google.gerrit.entities.BranchNameKey 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)

Aggregations

BranchNameKey (com.google.gerrit.entities.BranchNameKey)75 Test (org.junit.Test)48 Project (com.google.gerrit.entities.Project)26 AbstractDaemonTest (com.google.gerrit.acceptance.AbstractDaemonTest)25 Config (org.eclipse.jgit.lib.Config)19 SubmoduleSubscription (com.google.gerrit.entities.SubmoduleSubscription)18 PushOneCommit (com.google.gerrit.acceptance.PushOneCommit)16 RevCommit (org.eclipse.jgit.revwalk.RevCommit)16 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)15 AuthException (com.google.gerrit.extensions.restapi.AuthException)13 Change (com.google.gerrit.entities.Change)12 IOException (java.io.IOException)11 ObjectId (org.eclipse.jgit.lib.ObjectId)11 StorageException (com.google.gerrit.exceptions.StorageException)10 ChangeData (com.google.gerrit.server.query.change.ChangeData)9 Repository (org.eclipse.jgit.lib.Repository)9 PatchSet (com.google.gerrit.entities.PatchSet)8 CodeReviewCommit (com.google.gerrit.server.git.CodeReviewCommit)8 HashMap (java.util.HashMap)7 Ref (org.eclipse.jgit.lib.Ref)7