Search in sources :

Example 1 with MergeableInfo

use of com.google.gerrit.extensions.common.MergeableInfo in project gerrit by GerritCodeReview.

the class CheckMergeability method apply.

@Override
public MergeableInfo apply(BranchResource resource) throws IOException, BadRequestException, ResourceNotFoundException {
    if (!(submitType.equals(SubmitType.MERGE_ALWAYS) || submitType.equals(SubmitType.MERGE_IF_NECESSARY))) {
        throw new BadRequestException("Submit type: " + submitType + " is not supported");
    }
    MergeableInfo result = new MergeableInfo();
    result.submitType = submitType;
    result.strategy = strategy;
    try (Repository git = gitManager.openRepository(resource.getNameKey());
        RevWalk rw = new RevWalk(git);
        ObjectInserter inserter = new InMemoryInserter(git)) {
        Merger m = MergeUtil.newMerger(inserter, git.getConfig(), strategy);
        Ref destRef = git.getRefDatabase().exactRef(resource.getRef());
        if (destRef == null) {
            throw new ResourceNotFoundException(resource.getRef());
        }
        RevCommit targetCommit = rw.parseCommit(destRef.getObjectId());
        RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, source);
        if (!resource.getControl().canReadCommit(db.get(), git, sourceCommit)) {
            throw new BadRequestException("do not have read permission for: " + source);
        }
        if (rw.isMergedInto(sourceCommit, targetCommit)) {
            result.mergeable = true;
            result.commitMerged = true;
            result.contentMerged = true;
            return result;
        }
        if (m.merge(false, targetCommit, sourceCommit)) {
            result.mergeable = true;
            result.commitMerged = false;
            result.contentMerged = m.getResultTreeId().equals(targetCommit.getTree());
        } else {
            result.mergeable = false;
            if (m instanceof ResolveMerger) {
                result.conflicts = ((ResolveMerger) m).getUnmergedPaths();
            }
        }
    } catch (IllegalArgumentException e) {
        throw new BadRequestException(e.getMessage());
    }
    return result;
}
Also used : Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) Merger(org.eclipse.jgit.merge.Merger) ResolveMerger(org.eclipse.jgit.merge.ResolveMerger) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) MergeableInfo(com.google.gerrit.extensions.common.MergeableInfo) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) InMemoryInserter(com.google.gerrit.server.git.InMemoryInserter) RevWalk(org.eclipse.jgit.revwalk.RevWalk) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) ResolveMerger(org.eclipse.jgit.merge.ResolveMerger) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 2 with MergeableInfo

use of com.google.gerrit.extensions.common.MergeableInfo in project gerrit by GerritCodeReview.

the class Mergeable method apply.

@Override
public MergeableInfo apply(RevisionResource resource) throws AuthException, ResourceConflictException, BadRequestException, OrmException, IOException {
    Change change = resource.getChange();
    PatchSet ps = resource.getPatchSet();
    MergeableInfo result = new MergeableInfo();
    if (!change.getStatus().isOpen()) {
        throw new ResourceConflictException("change is " + ChangeUtil.status(change));
    } else if (!ps.getId().equals(change.currentPatchSetId())) {
        // Only the current revision is mergeable. Others always fail.
        return result;
    }
    ChangeData cd = changeDataFactory.create(db.get(), resource.getControl());
    result.submitType = getSubmitType(cd, ps);
    try (Repository git = gitManager.openRepository(change.getProject())) {
        ObjectId commit = toId(ps);
        Ref ref = git.getRefDatabase().exactRef(change.getDest().get());
        ProjectState projectState = projectCache.get(change.getProject());
        String strategy = mergeUtilFactory.create(projectState).mergeStrategyName();
        result.strategy = strategy;
        result.mergeable = isMergable(git, change, commit, ref, result.submitType, strategy);
        if (otherBranches) {
            result.mergeableInto = new ArrayList<>();
            BranchOrderSection branchOrder = projectState.getBranchOrderSection();
            if (branchOrder != null) {
                int prefixLen = Constants.R_HEADS.length();
                String[] names = branchOrder.getMoreStable(ref.getName());
                Map<String, Ref> refs = git.getRefDatabase().exactRef(names);
                for (String n : names) {
                    Ref other = refs.get(n);
                    if (other == null) {
                        continue;
                    }
                    if (cache.get(commit, other, SubmitType.CHERRY_PICK, strategy, change.getDest(), git)) {
                        result.mergeableInto.add(other.getName().substring(prefixLen));
                    }
                }
            }
        }
    }
    return result;
}
Also used : ObjectId(org.eclipse.jgit.lib.ObjectId) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) Change(com.google.gerrit.reviewdb.client.Change) BranchOrderSection(com.google.gerrit.server.git.BranchOrderSection) ChangeData(com.google.gerrit.server.query.change.ChangeData) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) MergeableInfo(com.google.gerrit.extensions.common.MergeableInfo) ProjectState(com.google.gerrit.server.project.ProjectState)

Example 3 with MergeableInfo

use of com.google.gerrit.extensions.common.MergeableInfo in project gerrit by GerritCodeReview.

the class CheckMergeability method apply.

@Override
public Response<MergeableInfo> apply(BranchResource resource) throws IOException, BadRequestException, ResourceNotFoundException, ResourceConflictException {
    if (!(submitType.equals(SubmitType.MERGE_ALWAYS) || submitType.equals(SubmitType.MERGE_IF_NECESSARY))) {
        throw new BadRequestException("Submit type: " + submitType + " is not supported");
    }
    MergeableInfo result = new MergeableInfo();
    result.submitType = submitType;
    result.strategy = strategy;
    try (Repository git = gitManager.openRepository(resource.getNameKey());
        RevWalk rw = new RevWalk(git);
        ObjectInserter inserter = new InMemoryInserter(git)) {
        Merger m = MergeUtil.newMerger(inserter, git.getConfig(), strategy);
        Ref destRef = git.getRefDatabase().exactRef(resource.getRef());
        if (destRef == null) {
            throw new ResourceNotFoundException(resource.getRef());
        }
        RevCommit targetCommit = rw.parseCommit(destRef.getObjectId());
        RevCommit sourceCommit = null;
        try {
            sourceCommit = MergeUtil.resolveCommit(git, rw, source);
            if (!commits.canRead(resource.getProjectState(), git, sourceCommit)) {
                throw new BadRequestException("do not have read permission for: " + source);
            }
        } catch (BadRequestException e) {
            // Throw a unified exception for permission denied and unresolvable commits.
            throw new BadRequestException("Error resolving: '" + source + "'. Do not have read permission, or failed to resolve to a commit.", e);
        }
        if (rw.isMergedInto(sourceCommit, targetCommit)) {
            result.mergeable = true;
            result.commitMerged = true;
            result.contentMerged = true;
            return Response.ok(result);
        }
        if (m.merge(false, targetCommit, sourceCommit)) {
            result.mergeable = true;
            result.commitMerged = false;
            result.contentMerged = m.getResultTreeId().equals(targetCommit.getTree());
        } else {
            result.mergeable = false;
            if (m instanceof ResolveMerger) {
                result.conflicts = ((ResolveMerger) m).getUnmergedPaths();
            }
        }
    } catch (InvalidMergeStrategyException e) {
        throw new BadRequestException(e.getMessage());
    } catch (NoMergeBaseException e) {
        // adapted to show the message to the user.
        throw new ResourceConflictException(String.format("Change cannot be merged: %s", e.getMessage()), e);
    }
    return Response.ok(result);
}
Also used : NoMergeBaseException(org.eclipse.jgit.errors.NoMergeBaseException) InMemoryInserter(com.google.gerrit.server.git.InMemoryInserter) RevWalk(org.eclipse.jgit.revwalk.RevWalk) ResolveMerger(org.eclipse.jgit.merge.ResolveMerger) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Merger(org.eclipse.jgit.merge.Merger) ResolveMerger(org.eclipse.jgit.merge.ResolveMerger) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) MergeableInfo(com.google.gerrit.extensions.common.MergeableInfo) InvalidMergeStrategyException(com.google.gerrit.exceptions.InvalidMergeStrategyException) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 4 with MergeableInfo

use of com.google.gerrit.extensions.common.MergeableInfo in project gerrit by GerritCodeReview.

the class CheckMergeabilityIT method assertMergeable.

private void assertMergeable(String targetBranch, String source, String strategy) throws Exception {
    MergeableInfo mergeableInfo = getMergeableInfo(targetBranch, source, strategy);
    assertThat(mergeableInfo.mergeable).isTrue();
}
Also used : MergeableInfo(com.google.gerrit.extensions.common.MergeableInfo)

Example 5 with MergeableInfo

use of com.google.gerrit.extensions.common.MergeableInfo in project gerrit by GerritCodeReview.

the class CheckMergeabilityIT method assertUnMergeable.

private void assertUnMergeable(String targetBranch, String source, String strategy, String... conflicts) throws Exception {
    MergeableInfo mergeableInfo = getMergeableInfo(targetBranch, source, strategy);
    assertThat(mergeableInfo.mergeable).isFalse();
    assertThat(mergeableInfo.conflicts).containsExactly((Object[]) conflicts);
}
Also used : MergeableInfo(com.google.gerrit.extensions.common.MergeableInfo)

Aggregations

MergeableInfo (com.google.gerrit.extensions.common.MergeableInfo)11 Ref (org.eclipse.jgit.lib.Ref)4 Repository (org.eclipse.jgit.lib.Repository)4 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)3 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)2 ResourceNotFoundException (com.google.gerrit.extensions.restapi.ResourceNotFoundException)2 InMemoryInserter (com.google.gerrit.server.git.InMemoryInserter)2 ProjectState (com.google.gerrit.server.project.ProjectState)2 ChangeData (com.google.gerrit.server.query.change.ChangeData)2 ObjectId (org.eclipse.jgit.lib.ObjectId)2 ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)2 Merger (org.eclipse.jgit.merge.Merger)2 ResolveMerger (org.eclipse.jgit.merge.ResolveMerger)2 RevCommit (org.eclipse.jgit.revwalk.RevCommit)2 RevWalk (org.eclipse.jgit.revwalk.RevWalk)2 AbstractDaemonTest (com.google.gerrit.acceptance.AbstractDaemonTest)1 PushOneCommit (com.google.gerrit.acceptance.PushOneCommit)1 RestResponse (com.google.gerrit.acceptance.RestResponse)1 BranchOrderSection (com.google.gerrit.entities.BranchOrderSection)1 Change (com.google.gerrit.entities.Change)1