Example usage for org.eclipse.jgit.merge ThreeWayMerger setBase

List of usage examples for org.eclipse.jgit.merge ThreeWayMerger setBase

Introduction

In this page you can find the example usage for org.eclipse.jgit.merge ThreeWayMerger setBase.

Prototype

public void setBase(AnyObjectId id) throws MissingObjectException, IncorrectObjectTypeException, IOException 

Source Link

Document

Set the common ancestor tree.

Usage

From source file:com.gitblit.utils.JGitUtils.java

License:Apache License

public static boolean commitIndex(Repository db, String branch, DirCache index, ObjectId parentId,
        boolean forceCommit, String author, String authorEmail, String message)
        throws IOException, ConcurrentRefUpdateException {
    boolean success = false;

    ObjectId headId = db.resolve(branch + "^{commit}");
    ObjectId baseId = parentId;/*from   w w w . ja  v  a 2  s  .  com*/
    if (baseId == null || headId == null) {
        return false;
    }

    ObjectInserter odi = db.newObjectInserter();
    try {
        // Create the in-memory index of the new/updated ticket
        ObjectId indexTreeId = index.writeTree(odi);

        // Create a commit object
        PersonIdent ident = new PersonIdent(author, authorEmail);

        if (forceCommit == false) {
            ThreeWayMerger merger = MergeStrategy.RECURSIVE.newMerger(db, true);
            merger.setObjectInserter(odi);
            merger.setBase(baseId);
            boolean mergeSuccess = merger.merge(indexTreeId, headId);

            if (mergeSuccess) {
                indexTreeId = merger.getResultTreeId();
            } else {
                //Manual merge required
                return false;
            }
        }

        CommitBuilder commit = new CommitBuilder();
        commit.setAuthor(ident);
        commit.setCommitter(ident);
        commit.setEncoding(com.gitblit.Constants.ENCODING);
        commit.setMessage(message);
        commit.setParentId(headId);
        commit.setTreeId(indexTreeId);

        // Insert the commit into the repository
        ObjectId commitId = odi.insert(commit);
        odi.flush();

        RevWalk revWalk = new RevWalk(db);
        try {
            RevCommit revCommit = revWalk.parseCommit(commitId);
            RefUpdate ru = db.updateRef(branch);
            ru.setForceUpdate(forceCommit);
            ru.setNewObjectId(commitId);
            ru.setExpectedOldObjectId(headId);
            ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false);
            Result rc = ru.update();

            switch (rc) {
            case NEW:
            case FORCED:
            case FAST_FORWARD:
                success = true;
                break;
            case REJECTED:
            case LOCK_FAILURE:
                throw new ConcurrentRefUpdateException(JGitText.get().couldNotLockHEAD, ru.getRef(), rc);
            default:
                throw new JGitInternalException(MessageFormat.format(JGitText.get().updatingRefFailed, branch,
                        commitId.toString(), rc));
            }
        } finally {
            revWalk.close();
        }
    } finally {
        odi.close();
    }
    return success;
}

From source file:com.google.gerrit.server.change.RebaseChange.java

License:Apache License

/**
 * Rebase a commit./*from  ww  w . j a v  a 2 s .c om*/
 *
 * @param git repository to find commits in.
 * @param inserter inserter to handle new trees and blobs.
 * @param original the commit to rebase.
 * @param base base to rebase against.
 * @param mergeUtil merge utilities for the destination project.
 * @param committerIdent committer identity.
 * @return the id of the rebased commit.
 * @throws MergeConflictException the rebase failed due to a merge conflict.
 * @throws IOException the merge failed for another reason.
 */
private ObjectId rebaseCommit(Repository git, ObjectInserter inserter, RevCommit original, RevCommit base,
        MergeUtil mergeUtil, PersonIdent committerIdent)
        throws MergeConflictException, IOException, InvalidChangeOperationException {
    RevCommit parentCommit = original.getParent(0);

    if (base.equals(parentCommit)) {
        throw new InvalidChangeOperationException("Change is already up to date.");
    }

    ThreeWayMerger merger = mergeUtil.newThreeWayMerger(git, inserter);
    merger.setBase(parentCommit);
    merger.merge(original, base);

    if (merger.getResultTreeId() == null) {
        throw new MergeConflictException("The change could not be rebased due to a conflict during merge.");
    }

    CommitBuilder cb = new CommitBuilder();
    cb.setTreeId(merger.getResultTreeId());
    cb.setParentId(base);
    cb.setAuthor(original.getAuthorIdent());
    cb.setMessage(original.getFullMessage());
    cb.setCommitter(committerIdent);
    ObjectId objectId = inserter.insert(cb);
    inserter.flush();
    return objectId;
}

From source file:com.google.gerrit.server.change.RebaseChangeOp.java

License:Apache License

/**
 * Rebase a commit./*from  w ww  . jav a  2s  . c  o m*/
 *
 * @param ctx repo context.
 * @param original the commit to rebase.
 * @param base base to rebase against.
 * @return the rebased commit.
 * @throws MergeConflictException the rebase failed due to a merge conflict.
 * @throws IOException the merge failed for another reason.
 */
private RevCommit rebaseCommit(RepoContext ctx, RevCommit original, ObjectId base)
        throws ResourceConflictException, MergeConflictException, IOException {
    RevCommit parentCommit = original.getParent(0);

    if (base.equals(parentCommit)) {
        throw new ResourceConflictException("Change is already up to date.");
    }

    ThreeWayMerger merger = newMergeUtil().newThreeWayMerger(ctx.getRepository(), ctx.getInserter());
    merger.setBase(parentCommit);
    merger.merge(original, base);

    if (merger.getResultTreeId() == null) {
        throw new MergeConflictException("The change could not be rebased due to a conflict during merge.");
    }

    CommitBuilder cb = new CommitBuilder();
    cb.setTreeId(merger.getResultTreeId());
    cb.setParentId(base);
    cb.setAuthor(original.getAuthorIdent());
    cb.setMessage(original.getFullMessage());
    if (committerIdent != null) {
        cb.setCommitter(committerIdent);
    } else {
        cb.setCommitter(ctx.getUser().asIdentifiedUser().newCommitterIdent(ctx.getWhen(), ctx.getTimeZone()));
    }
    ObjectId objectId = ctx.getInserter().insert(cb);
    ctx.getInserter().flush();
    return ctx.getRevWalk().parseCommit(objectId);
}

From source file:com.google.gerrit.server.changedetail.RebaseChange.java

License:Apache License

/**
 * Rebase a commit./*from   w  w w  . jav  a2 s .  c o m*/
 *
 * @param git repository to find commits in.
 * @param inserter inserter to handle new trees and blobs.
 * @param original the commit to rebase.
 * @param base base to rebase against.
 * @param mergeUtil merge utilities for the destination project.
 * @param committerIdent committer identity.
 * @return the id of the rebased commit.
 * @throws MergeConflictException the rebase failed due to a merge conflict.
 * @throws IOException the merge failed for another reason.
 */
private ObjectId rebaseCommit(Repository git, ObjectInserter inserter, RevCommit original, RevCommit base,
        MergeUtil mergeUtil, PersonIdent committerIdent) throws MergeConflictException, IOException {
    RevCommit parentCommit = original.getParent(0);

    if (base.equals(parentCommit)) {
        throw new IOException("Change is already up to date.");
    }

    ThreeWayMerger merger = mergeUtil.newThreeWayMerger(git, inserter);
    merger.setBase(parentCommit);
    merger.merge(original, base);

    if (merger.getResultTreeId() == null) {
        throw new MergeConflictException("The change could not be rebased due to a conflict during merge.");
    }

    CommitBuilder cb = new CommitBuilder();
    cb.setTreeId(merger.getResultTreeId());
    cb.setParentId(base);
    cb.setAuthor(original.getAuthorIdent());
    cb.setMessage(original.getFullMessage());
    cb.setCommitter(committerIdent);
    ObjectId objectId = inserter.insert(cb);
    inserter.flush();
    return objectId;
}

From source file:com.google.gerrit.server.edit.ChangeEditModifier.java

License:Apache License

/**
 * Rebase change edit on latest patch set
 *
 * @param edit change edit that contains edit to rebase
 * @param current patch set to rebase the edit on
 * @throws AuthException//from  w  w  w . ja v a 2  s. c  om
 * @throws ResourceConflictException thrown if rebase fails due to merge conflicts
 * @throws InvalidChangeOperationException
 * @throws IOException
 */
public void rebaseEdit(ChangeEdit edit, PatchSet current)
        throws AuthException, ResourceConflictException, InvalidChangeOperationException, IOException {
    if (!currentUser.get().isIdentifiedUser()) {
        throw new AuthException("Authentication required");
    }

    Change change = edit.getChange();
    IdentifiedUser me = (IdentifiedUser) currentUser.get();
    String refName = RefNames.refsEdit(me.getAccountId(), change.getId(), current.getId());
    try (Repository repo = gitManager.openRepository(change.getProject());
            RevWalk rw = new RevWalk(repo);
            ObjectInserter inserter = repo.newObjectInserter()) {
        BatchRefUpdate ru = repo.getRefDatabase().newBatchUpdate();
        RevCommit editCommit = edit.getEditCommit();
        if (editCommit.getParentCount() == 0) {
            throw new InvalidChangeOperationException("Rebase edit against root commit not supported");
        }
        RevCommit tip = rw.parseCommit(ObjectId.fromString(current.getRevision().get()));
        ThreeWayMerger m = MergeStrategy.RESOLVE.newMerger(repo, true);
        m.setObjectInserter(inserter);
        m.setBase(ObjectId.fromString(edit.getBasePatchSet().getRevision().get()));

        if (m.merge(tip, editCommit)) {
            ObjectId tree = m.getResultTreeId();

            CommitBuilder commit = new CommitBuilder();
            commit.setTreeId(tree);
            for (int i = 0; i < tip.getParentCount(); i++) {
                commit.addParentId(tip.getParent(i));
            }
            commit.setAuthor(editCommit.getAuthorIdent());
            commit.setCommitter(new PersonIdent(editCommit.getCommitterIdent(), TimeUtil.nowTs()));
            commit.setMessage(editCommit.getFullMessage());
            ObjectId newEdit = inserter.insert(commit);
            inserter.flush();

            ru.addCommand(new ReceiveCommand(ObjectId.zeroId(), newEdit, refName));
            ru.addCommand(
                    new ReceiveCommand(edit.getRef().getObjectId(), ObjectId.zeroId(), edit.getRefName()));
            ru.execute(rw, NullProgressMonitor.INSTANCE);
            for (ReceiveCommand cmd : ru.getCommands()) {
                if (cmd.getResult() != ReceiveCommand.Result.OK) {
                    throw new IOException("failed: " + cmd);
                }
            }
        } else {
            // TODO(davido): Allow to resolve conflicts inline
            throw new ResourceConflictException("merge conflict");
        }
    }
}

From source file:com.google.gerrit.server.git.MergeUtil.java

License:Apache License

public CodeReviewCommit createCherryPickFromCommit(Repository repo, ObjectInserter inserter, RevCommit mergeTip,
        RevCommit originalCommit, PersonIdent cherryPickCommitterIdent, String commitMsg, CodeReviewRevWalk rw)
        throws MissingObjectException, IncorrectObjectTypeException, IOException, MergeIdenticalTreeException,
        MergeConflictException {//from ww  w  . ja  v  a2  s  . c o m

    final ThreeWayMerger m = newThreeWayMerger(repo, inserter);

    m.setBase(originalCommit.getParent(0));
    if (m.merge(mergeTip, originalCommit)) {
        ObjectId tree = m.getResultTreeId();
        if (tree.equals(mergeTip.getTree())) {
            throw new MergeIdenticalTreeException("identical tree");
        }

        CommitBuilder mergeCommit = new CommitBuilder();
        mergeCommit.setTreeId(tree);
        mergeCommit.setParentId(mergeTip);
        mergeCommit.setAuthor(originalCommit.getAuthorIdent());
        mergeCommit.setCommitter(cherryPickCommitterIdent);
        mergeCommit.setMessage(commitMsg);
        return rw.parseCommit(commit(inserter, mergeCommit));
    } else {
        throw new MergeConflictException("merge conflict");
    }
}

From source file:com.google.gerrit.server.git.MergeUtil.java

License:Apache License

public boolean canCherryPick(MergeSorter mergeSorter, Repository repo, CodeReviewCommit mergeTip,
        CodeReviewRevWalk rw, CodeReviewCommit toMerge) throws MergeException {
    if (mergeTip == null) {
        // The branch is unborn. Fast-forward is possible.
        ///*ww  w .j  a va  2s.  c  o  m*/
        return true;
    }

    if (toMerge.getParentCount() == 0) {
        // Refuse to merge a root commit into an existing branch,
        // we cannot obtain a delta for the cherry-pick to apply.
        //
        return false;
    }

    if (toMerge.getParentCount() == 1) {
        // If there is only one parent, a cherry-pick can be done by
        // taking the delta relative to that one parent and redoing
        // that on the current merge tip.
        //
        try {
            ThreeWayMerger m = newThreeWayMerger(repo, createDryRunInserter(repo));
            m.setBase(toMerge.getParent(0));
            return m.merge(mergeTip, toMerge);
        } catch (IOException e) {
            throw new MergeException("Cannot merge " + toMerge.name(), e);
        }
    }

    // There are multiple parents, so this is a merge commit. We
    // don't want to cherry-pick the merge as clients can't easily
    // rebase their history with that merge present and replaced
    // by an equivalent merge with a different first parent. So
    // instead behave as though MERGE_IF_NECESSARY was configured.
    //
    return canFastForward(mergeSorter, mergeTip, rw, toMerge) || canMerge(mergeSorter, repo, mergeTip, toMerge);
}

From source file:org.uberfire.java.nio.fs.jgit.util.commands.Merge.java

License:Apache License

private void canMerge(final Repository repo, final RevCommit commonAncestor, final RevCommit sourceCommitTree,
        final RevCommit targetCommitTree, final String sourceBranch, final String targetBranch) {
    try {/*w  w w  .  j a v a2 s  . c o m*/
        ThreeWayMerger merger = MergeStrategy.RECURSIVE.newMerger(repo, true);
        merger.setBase(commonAncestor);
        boolean canMerge = merger.merge(sourceCommitTree, targetCommitTree);
        if (!canMerge) {
            throw new GitException(String.format("Cannot merge braches from <%s> to <%s>, merge conflicts",
                    sourceBranch, targetBranch));
        }
    } catch (IOException e) {
        throw new GitException(String.format("Cannot merge braches from <%s> to <%s>, merge conflicts",
                sourceBranch, targetBranch), e);
    }
}