Search in sources :

Example 1 with InvalidMergeStrategyException

use of com.google.gerrit.exceptions.InvalidMergeStrategyException 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 2 with InvalidMergeStrategyException

use of com.google.gerrit.exceptions.InvalidMergeStrategyException in project gerrit by GerritCodeReview.

the class MergeUtil method createMergeCommit.

public static CodeReviewCommit createMergeCommit(ObjectInserter inserter, Config repoConfig, RevCommit mergeTip, RevCommit originalCommit, String mergeStrategy, boolean allowConflicts, PersonIdent authorIdent, PersonIdent committerIdent, String commitMsg, CodeReviewRevWalk rw) throws IOException, MergeIdenticalTreeException, MergeConflictException, InvalidMergeStrategyException {
    if (!MergeStrategy.THEIRS.getName().equals(mergeStrategy) && rw.isMergedInto(originalCommit, mergeTip)) {
        throw new ChangeAlreadyMergedException("'" + originalCommit.getName() + "' has already been merged");
    }
    Merger m = newMerger(inserter, repoConfig, mergeStrategy);
    DirCache dc = DirCache.newInCore();
    if (allowConflicts && m instanceof ResolveMerger) {
        // The DirCache must be set on ResolveMerger before calling
        // ResolveMerger#merge(AnyObjectId...) otherwise the entries in DirCache don't get populated.
        ((ResolveMerger) m).setDirCache(dc);
    }
    ObjectId tree;
    ImmutableSet<String> filesWithGitConflicts;
    if (m.merge(false, mergeTip, originalCommit)) {
        filesWithGitConflicts = null;
        tree = m.getResultTreeId();
    } else {
        List<String> conflicts = ImmutableList.of();
        if (m instanceof ResolveMerger) {
            conflicts = ((ResolveMerger) m).getUnmergedPaths();
        }
        if (!allowConflicts) {
            throw new MergeConflictException(createConflictMessage(conflicts));
        }
        // For merging with conflict markers we need a ResolveMerger, double-check that we have one.
        if (!(m instanceof ResolveMerger)) {
            throw new MergeWithConflictsNotSupportedException(MergeStrategy.get(mergeStrategy));
        }
        Map<String, MergeResult<? extends Sequence>> mergeResults = ((ResolveMerger) m).getMergeResults();
        filesWithGitConflicts = mergeResults.entrySet().stream().filter(e -> e.getValue().containsConflicts()).map(Map.Entry::getKey).collect(toImmutableSet());
        tree = mergeWithConflicts(rw, inserter, dc, "TARGET BRANCH", mergeTip, "SOURCE BRANCH", originalCommit, mergeResults);
    }
    CommitBuilder mergeCommit = new CommitBuilder();
    mergeCommit.setTreeId(tree);
    mergeCommit.setParentIds(mergeTip, originalCommit);
    mergeCommit.setAuthor(authorIdent);
    mergeCommit.setCommitter(committerIdent);
    mergeCommit.setMessage(commitMsg);
    CodeReviewCommit commit = rw.parseCommit(inserter.insert(mergeCommit));
    commit.setFilesWithGitConflicts(filesWithGitConflicts);
    return commit;
}
Also used : ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) RevisionSyntaxException(org.eclipse.jgit.errors.RevisionSyntaxException) Comparator.naturalOrder(java.util.Comparator.naturalOrder) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) DynamicItem(com.google.gerrit.extensions.registration.DynamicItem) MissingObjectException(org.eclipse.jgit.errors.MissingObjectException) ThreeWayMergeStrategy(org.eclipse.jgit.merge.ThreeWayMergeStrategy) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) Merger(org.eclipse.jgit.merge.Merger) Assisted(com.google.inject.assistedinject.Assisted) FooterKey(org.eclipse.jgit.revwalk.FooterKey) RevWalk(org.eclipse.jgit.revwalk.RevWalk) PatchSetApproval(com.google.gerrit.entities.PatchSetApproval) Config(org.eclipse.jgit.lib.Config) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) InvalidMergeStrategyException(com.google.gerrit.exceptions.InvalidMergeStrategyException) MergeConflictException(com.google.gerrit.extensions.restapi.MergeConflictException) FooterLine(org.eclipse.jgit.revwalk.FooterLine) LabelType(com.google.gerrit.entities.LabelType) Map(java.util.Map) AssistedInject(com.google.inject.assistedinject.AssistedInject) UrlFormatter(com.google.gerrit.server.config.UrlFormatter) ImmutableSortedSet.toImmutableSortedSet(com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet) ImmutableSet(com.google.common.collect.ImmutableSet) Sequence(org.eclipse.jgit.diff.Sequence) GerritServerConfig(com.google.gerrit.server.config.GerritServerConfig) Collection(java.util.Collection) LargeObjectException(org.eclipse.jgit.errors.LargeObjectException) Account(com.google.gerrit.entities.Account) Set(java.util.Set) RevSort(org.eclipse.jgit.revwalk.RevSort) Constants(org.eclipse.jgit.lib.Constants) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) Collectors.joining(java.util.stream.Collectors.joining) Sets(com.google.common.collect.Sets) BranchNameKey(com.google.gerrit.entities.BranchNameKey) ApprovalsUtil(com.google.gerrit.server.approval.ApprovalsUtil) MergeIdenticalTreeException(com.google.gerrit.server.submit.MergeIdenticalTreeException) MergeStrategy(org.eclipse.jgit.merge.MergeStrategy) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Objects(java.util.Objects) PersonIdent(org.eclipse.jgit.lib.PersonIdent) List(java.util.List) Nullable(com.google.gerrit.common.Nullable) BooleanProjectConfig(com.google.gerrit.entities.BooleanProjectConfig) DirCache(org.eclipse.jgit.dircache.DirCache) Optional(java.util.Optional) FluentLogger(com.google.common.flogger.FluentLogger) AmbiguousObjectException(org.eclipse.jgit.errors.AmbiguousObjectException) Iterables(com.google.common.collect.Iterables) LabelId(com.google.gerrit.entities.LabelId) CodeReviewRevWalk(com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk) RevCommit(org.eclipse.jgit.revwalk.RevCommit) CommitMergeStatus(com.google.gerrit.server.submit.CommitMergeStatus) IncorrectObjectTypeException(org.eclipse.jgit.errors.IncorrectObjectTypeException) RevFlag(org.eclipse.jgit.revwalk.RevFlag) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry) HashMap(java.util.HashMap) DirCacheBuilder(org.eclipse.jgit.dircache.DirCacheBuilder) MergeBaseFailureReason(org.eclipse.jgit.errors.NoMergeBaseException.MergeBaseFailureReason) ChangeAlreadyMergedException(com.google.gerrit.server.submit.ChangeAlreadyMergedException) ArrayList(java.util.ArrayList) Strings(com.google.common.base.Strings) ImmutableList(com.google.common.collect.ImmutableList) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) ResolveMerger(org.eclipse.jgit.merge.ResolveMerger) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) MergeWithConflictsNotSupportedException(com.google.gerrit.exceptions.MergeWithConflictsNotSupportedException) Change(com.google.gerrit.entities.Change) PatchSet(com.google.gerrit.entities.PatchSet) ChangeUtil(com.google.gerrit.server.ChangeUtil) NoMergeBaseException(org.eclipse.jgit.errors.NoMergeBaseException) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) TemporaryBuffer(org.eclipse.jgit.util.TemporaryBuffer) Iterator(java.util.Iterator) ObjectIds.abbreviateName(com.google.gerrit.git.ObjectIds.abbreviateName) UTF_8(java.nio.charset.StandardCharsets.UTF_8) StorageException(com.google.gerrit.exceptions.StorageException) ProjectState(com.google.gerrit.server.project.ProjectState) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) ThreeWayMerger(org.eclipse.jgit.merge.ThreeWayMerger) ObjectId(org.eclipse.jgit.lib.ObjectId) MergeResult(org.eclipse.jgit.merge.MergeResult) MergeSorter(com.google.gerrit.server.submit.MergeSorter) MergeFormatter(org.eclipse.jgit.merge.MergeFormatter) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) FooterConstants(com.google.gerrit.common.FooterConstants) Collections(java.util.Collections) Repository(org.eclipse.jgit.lib.Repository) InputStream(java.io.InputStream) ObjectId(org.eclipse.jgit.lib.ObjectId) MergeResult(org.eclipse.jgit.merge.MergeResult) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) Sequence(org.eclipse.jgit.diff.Sequence) ResolveMerger(org.eclipse.jgit.merge.ResolveMerger) DirCache(org.eclipse.jgit.dircache.DirCache) MergeConflictException(com.google.gerrit.extensions.restapi.MergeConflictException) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry) Merger(org.eclipse.jgit.merge.Merger) ResolveMerger(org.eclipse.jgit.merge.ResolveMerger) ThreeWayMerger(org.eclipse.jgit.merge.ThreeWayMerger) MergeWithConflictsNotSupportedException(com.google.gerrit.exceptions.MergeWithConflictsNotSupportedException) ChangeAlreadyMergedException(com.google.gerrit.server.submit.ChangeAlreadyMergedException)

Example 3 with InvalidMergeStrategyException

use of com.google.gerrit.exceptions.InvalidMergeStrategyException in project gerrit by GerritCodeReview.

the class MergeUtil method createCherryPickFromCommit.

public CodeReviewCommit createCherryPickFromCommit(ObjectInserter inserter, Config repoConfig, RevCommit mergeTip, RevCommit originalCommit, PersonIdent cherryPickCommitterIdent, String commitMsg, CodeReviewRevWalk rw, int parentIndex, boolean ignoreIdenticalTree, boolean allowConflicts) throws IOException, MergeIdenticalTreeException, MergeConflictException, MethodNotAllowedException, InvalidMergeStrategyException {
    ThreeWayMerger m = newThreeWayMerger(inserter, repoConfig);
    m.setBase(originalCommit.getParent(parentIndex));
    DirCache dc = DirCache.newInCore();
    if (allowConflicts && m instanceof ResolveMerger) {
        // The DirCache must be set on ResolveMerger before calling
        // ResolveMerger#merge(AnyObjectId...) otherwise the entries in DirCache don't get populated.
        ((ResolveMerger) m).setDirCache(dc);
    }
    ObjectId tree;
    ImmutableSet<String> filesWithGitConflicts;
    if (m.merge(mergeTip, originalCommit)) {
        filesWithGitConflicts = null;
        tree = m.getResultTreeId();
        if (tree.equals(mergeTip.getTree()) && !ignoreIdenticalTree) {
            throw new MergeIdenticalTreeException("identical tree");
        }
    } else {
        if (!allowConflicts) {
            throw new MergeConflictException(String.format("merge conflict while merging commits %s and %s", mergeTip.toObjectId(), originalCommit.toObjectId()));
        }
        if (!useContentMerge) {
            // conflict markers.
            throw new MethodNotAllowedException("Cherry-pick with allow conflicts requires that content merge is enabled.");
        }
        // For merging with conflict markers we need a ResolveMerger, double-check that we have one.
        checkState(m instanceof ResolveMerger, "allow conflicts is not supported");
        Map<String, MergeResult<? extends Sequence>> mergeResults = ((ResolveMerger) m).getMergeResults();
        filesWithGitConflicts = mergeResults.entrySet().stream().filter(e -> e.getValue().containsConflicts()).map(Map.Entry::getKey).collect(toImmutableSet());
        tree = mergeWithConflicts(rw, inserter, dc, "HEAD", mergeTip, "CHANGE", originalCommit, mergeResults);
    }
    CommitBuilder cherryPickCommit = new CommitBuilder();
    cherryPickCommit.setTreeId(tree);
    cherryPickCommit.setParentId(mergeTip);
    cherryPickCommit.setAuthor(originalCommit.getAuthorIdent());
    cherryPickCommit.setCommitter(cherryPickCommitterIdent);
    cherryPickCommit.setMessage(commitMsg);
    matchAuthorToCommitterDate(project, cherryPickCommit);
    CodeReviewCommit commit = rw.parseCommit(inserter.insert(cherryPickCommit));
    commit.setFilesWithGitConflicts(filesWithGitConflicts);
    return commit;
}
Also used : ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) RevisionSyntaxException(org.eclipse.jgit.errors.RevisionSyntaxException) Comparator.naturalOrder(java.util.Comparator.naturalOrder) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) DynamicItem(com.google.gerrit.extensions.registration.DynamicItem) MissingObjectException(org.eclipse.jgit.errors.MissingObjectException) ThreeWayMergeStrategy(org.eclipse.jgit.merge.ThreeWayMergeStrategy) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) Merger(org.eclipse.jgit.merge.Merger) Assisted(com.google.inject.assistedinject.Assisted) FooterKey(org.eclipse.jgit.revwalk.FooterKey) RevWalk(org.eclipse.jgit.revwalk.RevWalk) PatchSetApproval(com.google.gerrit.entities.PatchSetApproval) Config(org.eclipse.jgit.lib.Config) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) InvalidMergeStrategyException(com.google.gerrit.exceptions.InvalidMergeStrategyException) MergeConflictException(com.google.gerrit.extensions.restapi.MergeConflictException) FooterLine(org.eclipse.jgit.revwalk.FooterLine) LabelType(com.google.gerrit.entities.LabelType) Map(java.util.Map) AssistedInject(com.google.inject.assistedinject.AssistedInject) UrlFormatter(com.google.gerrit.server.config.UrlFormatter) ImmutableSortedSet.toImmutableSortedSet(com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet) ImmutableSet(com.google.common.collect.ImmutableSet) Sequence(org.eclipse.jgit.diff.Sequence) GerritServerConfig(com.google.gerrit.server.config.GerritServerConfig) Collection(java.util.Collection) LargeObjectException(org.eclipse.jgit.errors.LargeObjectException) Account(com.google.gerrit.entities.Account) Set(java.util.Set) RevSort(org.eclipse.jgit.revwalk.RevSort) Constants(org.eclipse.jgit.lib.Constants) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) Collectors.joining(java.util.stream.Collectors.joining) Sets(com.google.common.collect.Sets) BranchNameKey(com.google.gerrit.entities.BranchNameKey) ApprovalsUtil(com.google.gerrit.server.approval.ApprovalsUtil) MergeIdenticalTreeException(com.google.gerrit.server.submit.MergeIdenticalTreeException) MergeStrategy(org.eclipse.jgit.merge.MergeStrategy) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Objects(java.util.Objects) PersonIdent(org.eclipse.jgit.lib.PersonIdent) List(java.util.List) Nullable(com.google.gerrit.common.Nullable) BooleanProjectConfig(com.google.gerrit.entities.BooleanProjectConfig) DirCache(org.eclipse.jgit.dircache.DirCache) Optional(java.util.Optional) FluentLogger(com.google.common.flogger.FluentLogger) AmbiguousObjectException(org.eclipse.jgit.errors.AmbiguousObjectException) Iterables(com.google.common.collect.Iterables) LabelId(com.google.gerrit.entities.LabelId) CodeReviewRevWalk(com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk) RevCommit(org.eclipse.jgit.revwalk.RevCommit) CommitMergeStatus(com.google.gerrit.server.submit.CommitMergeStatus) IncorrectObjectTypeException(org.eclipse.jgit.errors.IncorrectObjectTypeException) RevFlag(org.eclipse.jgit.revwalk.RevFlag) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry) HashMap(java.util.HashMap) DirCacheBuilder(org.eclipse.jgit.dircache.DirCacheBuilder) MergeBaseFailureReason(org.eclipse.jgit.errors.NoMergeBaseException.MergeBaseFailureReason) ChangeAlreadyMergedException(com.google.gerrit.server.submit.ChangeAlreadyMergedException) ArrayList(java.util.ArrayList) Strings(com.google.common.base.Strings) ImmutableList(com.google.common.collect.ImmutableList) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) ResolveMerger(org.eclipse.jgit.merge.ResolveMerger) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) MergeWithConflictsNotSupportedException(com.google.gerrit.exceptions.MergeWithConflictsNotSupportedException) Change(com.google.gerrit.entities.Change) PatchSet(com.google.gerrit.entities.PatchSet) ChangeUtil(com.google.gerrit.server.ChangeUtil) NoMergeBaseException(org.eclipse.jgit.errors.NoMergeBaseException) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) TemporaryBuffer(org.eclipse.jgit.util.TemporaryBuffer) Iterator(java.util.Iterator) ObjectIds.abbreviateName(com.google.gerrit.git.ObjectIds.abbreviateName) UTF_8(java.nio.charset.StandardCharsets.UTF_8) StorageException(com.google.gerrit.exceptions.StorageException) ProjectState(com.google.gerrit.server.project.ProjectState) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) ThreeWayMerger(org.eclipse.jgit.merge.ThreeWayMerger) ObjectId(org.eclipse.jgit.lib.ObjectId) MergeResult(org.eclipse.jgit.merge.MergeResult) MergeSorter(com.google.gerrit.server.submit.MergeSorter) MergeFormatter(org.eclipse.jgit.merge.MergeFormatter) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) FooterConstants(com.google.gerrit.common.FooterConstants) Collections(java.util.Collections) Repository(org.eclipse.jgit.lib.Repository) InputStream(java.io.InputStream) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) ObjectId(org.eclipse.jgit.lib.ObjectId) MergeResult(org.eclipse.jgit.merge.MergeResult) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) ThreeWayMerger(org.eclipse.jgit.merge.ThreeWayMerger) Sequence(org.eclipse.jgit.diff.Sequence) ResolveMerger(org.eclipse.jgit.merge.ResolveMerger) MergeIdenticalTreeException(com.google.gerrit.server.submit.MergeIdenticalTreeException) DirCache(org.eclipse.jgit.dircache.DirCache) MergeConflictException(com.google.gerrit.extensions.restapi.MergeConflictException) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry)

Example 4 with InvalidMergeStrategyException

use of com.google.gerrit.exceptions.InvalidMergeStrategyException in project gerrit by GerritCodeReview.

the class CreateChange method createNewChange.

// TODO(issue-15517): Fix the JdkObsolete issue with Date once JGit's PersonIdent class supports
// Instants
@SuppressWarnings("JdkObsolete")
private ChangeInfo createNewChange(ChangeInput input, IdentifiedUser me, ProjectState projectState, BatchUpdate.Factory updateFactory) throws RestApiException, PermissionBackendException, IOException, ConfigInvalidException, UpdateException {
    logger.atFine().log("Creating new change for target branch %s in project %s" + " (new branch = %s, base change = %s, base commit = %s)", input.branch, projectState.getName(), input.newBranch, input.baseChange, input.baseCommit);
    try (Repository git = gitManager.openRepository(projectState.getNameKey());
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        CodeReviewRevWalk rw = CodeReviewCommit.newRevWalk(reader)) {
        PatchSet basePatchSet = null;
        List<String> groups = Collections.emptyList();
        if (input.baseChange != null) {
            ChangeNotes baseChange = getBaseChange(input.baseChange);
            basePatchSet = psUtil.current(baseChange);
            groups = basePatchSet.groups();
            logger.atFine().log("base patch set = %s (groups = %s)", basePatchSet.id(), groups);
        }
        ObjectId parentCommit = getParentCommit(git, rw, input.branch, input.newBranch, basePatchSet, input.baseCommit, input.merge);
        logger.atFine().log("parent commit = %s", parentCommit != null ? parentCommit.name() : "NULL");
        RevCommit mergeTip = parentCommit == null ? null : rw.parseCommit(parentCommit);
        Instant now = TimeUtil.now();
        PersonIdent committer = me.newCommitterIdent(now, serverTimeZone);
        PersonIdent author = input.author == null ? committer : new PersonIdent(input.author.name, input.author.email, Date.from(now), serverTimeZone);
        String commitMessage = getCommitMessage(input.subject, me);
        CodeReviewCommit c;
        if (input.merge != null) {
            // create a merge commit
            c = newMergeCommit(git, oi, rw, projectState, mergeTip, input.merge, author, committer, commitMessage);
            if (!c.getFilesWithGitConflicts().isEmpty()) {
                logger.atFine().log("merge commit has conflicts in the following files: %s", c.getFilesWithGitConflicts());
            }
        } else {
            // create an empty commit
            c = newCommit(oi, rw, author, committer, mergeTip, commitMessage);
        }
        // Flush inserter so that commit becomes visible to validators
        oi.flush();
        Change.Id changeId = Change.id(seq.nextChangeId());
        ChangeInserter ins = changeInserterFactory.create(changeId, c, input.branch);
        ins.setMessage(messageForNewChange(ins.getPatchSetId(), c));
        ins.setTopic(input.topic);
        ins.setPrivate(input.isPrivate);
        ins.setWorkInProgress(input.workInProgress || !c.getFilesWithGitConflicts().isEmpty());
        ins.setGroups(groups);
        if (input.validationOptions != null) {
            ImmutableListMultimap.Builder<String, String> validationOptions = ImmutableListMultimap.builder();
            input.validationOptions.entrySet().forEach(e -> validationOptions.put(e.getKey(), e.getValue()));
            ins.setValidationOptions(validationOptions.build());
        }
        try (BatchUpdate bu = updateFactory.create(projectState.getNameKey(), me, now)) {
            bu.setRepository(git, rw, oi);
            bu.setNotify(notifyResolver.resolve(firstNonNull(input.notify, NotifyHandling.ALL), input.notifyDetails));
            bu.insertChange(ins);
            bu.execute();
        }
        ChangeInfo changeInfo = jsonFactory.noOptions().format(ins.getChange());
        changeInfo.containsGitConflicts = !c.getFilesWithGitConflicts().isEmpty() ? true : null;
        return changeInfo;
    } catch (InvalidMergeStrategyException | MergeWithConflictsNotSupportedException e) {
        throw new BadRequestException(e.getMessage());
    }
}
Also used : ChangeInfo(com.google.gerrit.extensions.common.ChangeInfo) ObjectId(org.eclipse.jgit.lib.ObjectId) Instant(java.time.Instant) CodeReviewRevWalk(com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk) PatchSet(com.google.gerrit.entities.PatchSet) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) Change(com.google.gerrit.entities.Change) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) Repository(org.eclipse.jgit.lib.Repository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) InvalidMergeStrategyException(com.google.gerrit.exceptions.InvalidMergeStrategyException) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) MergeWithConflictsNotSupportedException(com.google.gerrit.exceptions.MergeWithConflictsNotSupportedException) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) ObjectReader(org.eclipse.jgit.lib.ObjectReader) ChangeInserter(com.google.gerrit.server.change.ChangeInserter) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 5 with InvalidMergeStrategyException

use of com.google.gerrit.exceptions.InvalidMergeStrategyException 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)

Aggregations

InvalidMergeStrategyException (com.google.gerrit.exceptions.InvalidMergeStrategyException)5 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)5 ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)5 Repository (org.eclipse.jgit.lib.Repository)5 RevCommit (org.eclipse.jgit.revwalk.RevCommit)5 Change (com.google.gerrit.entities.Change)4 PatchSet (com.google.gerrit.entities.PatchSet)4 MergeWithConflictsNotSupportedException (com.google.gerrit.exceptions.MergeWithConflictsNotSupportedException)4 ResourceNotFoundException (com.google.gerrit.extensions.restapi.ResourceNotFoundException)4 BranchNameKey (com.google.gerrit.entities.BranchNameKey)3 IdentifiedUser (com.google.gerrit.server.IdentifiedUser)3 NoMergeBaseException (org.eclipse.jgit.errors.NoMergeBaseException)3 Merger (org.eclipse.jgit.merge.Merger)3 ResolveMerger (org.eclipse.jgit.merge.ResolveMerger)3 RevWalk (org.eclipse.jgit.revwalk.RevWalk)3 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)2 Preconditions.checkState (com.google.common.base.Preconditions.checkState)2 Strings (com.google.common.base.Strings)2 ImmutableList (com.google.common.collect.ImmutableList)2 ImmutableSet (com.google.common.collect.ImmutableSet)2