Search in sources :

Example 1 with RebaseConflictsException

use of org.locationtech.geogig.api.porcelain.RebaseConflictsException in project GeoGig by boundlessgeo.

the class EndTransaction method run.

/**
     * Runs the command and builds the appropriate response.
     * 
     * @param context - the context to use for this command
     * 
     * @throws CommandSpecException
     */
@Override
public void run(CommandContext context) {
    if (this.getTransactionId() == null) {
        throw new CommandSpecException("There isn't a transaction to end.");
    }
    final Context transaction = this.getCommandLocator(context);
    TransactionEnd endTransaction = context.getGeoGIG().command(TransactionEnd.class);
    try {
        final boolean closed = endTransaction.setCancel(cancel).setTransaction((GeogigTransaction) transaction).call();
        context.setResponseContent(new CommandResponse() {

            @Override
            public void write(ResponseWriter out) throws Exception {
                out.start();
                if (closed) {
                    out.writeTransactionId(null);
                } else {
                    out.writeTransactionId(getTransactionId());
                }
                out.finish();
            }
        });
    } catch (MergeConflictsException m) {
        final RevCommit ours = context.getGeoGIG().getRepository().getCommit(m.getOurs());
        final RevCommit theirs = context.getGeoGIG().getRepository().getCommit(m.getTheirs());
        final Optional<ObjectId> ancestor = transaction.command(FindCommonAncestor.class).setLeft(ours).setRight(theirs).call();
        context.setResponseContent(new CommandResponse() {

            final MergeScenarioReport report = transaction.command(ReportMergeScenarioOp.class).setMergeIntoCommit(ours).setToMergeCommit(theirs).call();

            @Override
            public void write(ResponseWriter out) throws Exception {
                out.start();
                Optional<RevCommit> mergeCommit = Optional.absent();
                out.writeMergeResponse(mergeCommit, report, transaction, ours.getId(), theirs.getId(), ancestor.get());
                out.finish();
            }
        });
    } catch (RebaseConflictsException r) {
    // TODO: Handle rebase exception
    }
}
Also used : Context(org.locationtech.geogig.api.Context) CommandContext(org.locationtech.geogig.web.api.CommandContext) GeogigTransaction(org.locationtech.geogig.api.GeogigTransaction) Optional(com.google.common.base.Optional) RebaseConflictsException(org.locationtech.geogig.api.porcelain.RebaseConflictsException) CommandResponse(org.locationtech.geogig.web.api.CommandResponse) MergeScenarioReport(org.locationtech.geogig.api.plumbing.merge.MergeScenarioReport) MergeConflictsException(org.locationtech.geogig.api.porcelain.MergeConflictsException) RebaseConflictsException(org.locationtech.geogig.api.porcelain.RebaseConflictsException) CommandSpecException(org.locationtech.geogig.web.api.CommandSpecException) MergeConflictsException(org.locationtech.geogig.api.porcelain.MergeConflictsException) ResponseWriter(org.locationtech.geogig.web.api.ResponseWriter) CommandSpecException(org.locationtech.geogig.web.api.CommandSpecException) TransactionEnd(org.locationtech.geogig.api.plumbing.TransactionEnd) RevCommit(org.locationtech.geogig.api.RevCommit)

Example 2 with RebaseConflictsException

use of org.locationtech.geogig.api.porcelain.RebaseConflictsException in project GeoGig by boundlessgeo.

the class Rebase method runInternal.

/**
     * Executes the rebase command using the provided options.
     */
@Override
public void runInternal(GeogigCLI cli) throws IOException {
    checkParameter(!(skip && continueRebase), "Cannot use both --skip and --continue");
    checkParameter(!(skip && abort), "Cannot use both --skip and --abort");
    checkParameter(!(abort && continueRebase), "Cannot use both --abort and --continue");
    GeoGIG geogig = cli.getGeogig();
    RebaseOp rebase = geogig.command(RebaseOp.class).setSkip(skip).setContinue(continueRebase).setAbort(abort).setSquashMessage(squash);
    rebase.setProgressListener(cli.getProgressListener());
    if (arguments == null || arguments.size() == 0) {
        if (abort || skip || continueRebase) {
        } else {
            // Rebase onto remote branch
            throw new UnsupportedOperationException("remote branch rebase not yet supported");
        }
    } else {
        checkParameter(arguments.size() < 3, "Too many arguments specified.");
        if (arguments.size() == 2) {
            // Make sure branch is valid
            Optional<ObjectId> branchRef = geogig.command(RevParse.class).setRefSpec(arguments.get(1)).call();
            checkParameter(branchRef.isPresent(), "The branch reference could not be resolved.");
            // Checkout <branch> prior to rebase
            try {
                geogig.command(CheckoutOp.class).setSource(arguments.get(1)).call();
            } catch (CheckoutException e) {
                throw new CommandFailedException(e.getMessage(), e);
            }
        }
        Optional<Ref> upstreamRef = geogig.command(RefParse.class).setName(arguments.get(0)).call();
        checkParameter(upstreamRef.isPresent(), "The upstream reference could not be resolved.");
        rebase.setUpstream(Suppliers.ofInstance(upstreamRef.get().getObjectId()));
    }
    if (onto != null) {
        Optional<ObjectId> ontoId = geogig.command(RevParse.class).setRefSpec(onto).call();
        checkParameter(ontoId.isPresent(), "The onto reference could not be resolved.");
        rebase.setOnto(Suppliers.ofInstance(ontoId.get()));
    }
    try {
        rebase.call();
    } catch (RebaseConflictsException e) {
        StringBuilder sb = new StringBuilder();
        sb.append(e.getMessage() + "\n");
        sb.append("When you have fixed this conflicts, run 'geogig rebase --continue' to continue rebasing.\n");
        sb.append("If you would prefer to skip this commit, instead run 'geogig rebase --skip.\n");
        sb.append("To check out the original branch and stop rebasing, run 'geogig rebase --abort'\n");
        throw new CommandFailedException(sb.toString());
    }
    if (abort) {
        cli.getConsole().println("Rebase aborted successfully.");
    }
}
Also used : Ref(org.locationtech.geogig.api.Ref) ObjectId(org.locationtech.geogig.api.ObjectId) RebaseConflictsException(org.locationtech.geogig.api.porcelain.RebaseConflictsException) RebaseOp(org.locationtech.geogig.api.porcelain.RebaseOp) GeoGIG(org.locationtech.geogig.api.GeoGIG) CommandFailedException(org.locationtech.geogig.cli.CommandFailedException) CheckoutException(org.locationtech.geogig.api.porcelain.CheckoutException)

Example 3 with RebaseConflictsException

use of org.locationtech.geogig.api.porcelain.RebaseConflictsException in project GeoGig by boundlessgeo.

the class RebaseOpTest method testRebaseWithConflictAndContinue.

@Test
public void testRebaseWithConflictAndContinue() throws Exception {
    // Create the following revision graph
    // o
    // |
    // o - Points 1,2 added
    // |\
    // | o - branch1 - Points 1 modifiedB, 2 removed, 3 added
    // |
    // o - Points 1 modified, 2 removed
    // |
    // o - master - HEAD - Lines 1 added
    insertAndAdd(points1, points2);
    geogig.command(CommitOp.class).call();
    geogig.command(BranchCreateOp.class).setName("branch1").call();
    Feature points1Modified = feature(pointsType, idP1, "StringProp1_2", new Integer(1000), "POINT(1 1)");
    insert(points1Modified);
    delete(points2);
    geogig.command(AddOp.class).call();
    RevCommit masterCommit2 = geogig.command(CommitOp.class).setMessage("adding points1 modified, deleting point2").call();
    insert(lines1);
    geogig.command(AddOp.class).call();
    RevCommit masterCommit = geogig.command(CommitOp.class).setMessage("adding lines.1").call();
    geogig.command(CheckoutOp.class).setSource("branch1").call();
    insert(points3);
    Feature points1ModifiedB = feature(pointsType, idP1, "StringProp1_3", new Integer(2000), "POINT(1 1)");
    insert(points1ModifiedB);
    delete(points2);
    geogig.command(AddOp.class).call();
    RevCommit branchCommit = geogig.command(CommitOp.class).setMessage("branch commit").call();
    geogig.command(CheckoutOp.class).setSource("master").call();
    Ref branch1 = geogig.command(RefParse.class).setName("branch1").call().get();
    try {
        geogig.command(RebaseOp.class).setUpstream(Suppliers.ofInstance(branch1.getObjectId())).call();
        fail();
    } catch (RebaseConflictsException e) {
        assertTrue(e.getMessage().contains("conflict"));
    }
    Optional<Ref> ref = geogig.command(RefParse.class).setName(Ref.ORIG_HEAD).call();
    assertTrue(ref.isPresent());
    assertEquals(masterCommit.getId(), ref.get().getObjectId());
    List<Conflict> conflicts = geogig.command(ConflictsReadOp.class).call();
    assertEquals(1, conflicts.size());
    String path = NodeRef.appendChild(pointsName, idP1);
    assertEquals(conflicts.get(0).getPath(), path);
    assertEquals(conflicts.get(0).getOurs(), RevFeatureBuilder.build(points1Modified).getId());
    assertEquals(conflicts.get(0).getTheirs(), RevFeatureBuilder.build(points1ModifiedB).getId());
    // solve, and continue
    Feature points1Merged = feature(pointsType, idP1, "StringProp1_2", new Integer(2000), "POINT(1 1)");
    insert(points1Merged);
    geogig.command(AddOp.class).call();
    geogig.command(RebaseOp.class).setContinue(true).call();
    Iterator<RevCommit> log = geogig.command(LogOp.class).call();
    RevCommit logCommit1 = log.next();
    assertEquals(masterCommit.getAuthor(), logCommit1.getAuthor());
    assertEquals(masterCommit.getCommitter().getName(), logCommit1.getCommitter().getName());
    assertEquals(masterCommit.getMessage(), logCommit1.getMessage());
    assertEquals(masterCommit.getAuthor().getTimeZoneOffset(), logCommit1.getAuthor().getTimeZoneOffset());
    assertEquals(masterCommit.getAuthor().getTimestamp(), logCommit1.getAuthor().getTimestamp());
    assertEquals(masterCommit.getCommitter().getTimeZoneOffset(), logCommit1.getCommitter().getTimeZoneOffset());
    assertNotSame(masterCommit.getCommitter().getTimestamp(), logCommit1.getCommitter().getTimestamp());
    assertNotSame(masterCommit.getTreeId(), logCommit1.getTreeId());
    RevCommit logCommit2 = log.next();
    assertEquals(masterCommit2.getAuthor(), logCommit2.getAuthor());
    assertEquals(masterCommit2.getCommitter().getName(), logCommit2.getCommitter().getName());
    assertEquals(masterCommit2.getMessage(), logCommit2.getMessage());
    RevCommit logCommit3 = log.next();
    assertEquals(branchCommit.getAuthor(), logCommit3.getAuthor());
    assertEquals(branchCommit.getCommitter().getName(), logCommit3.getCommitter().getName());
    assertEquals(branchCommit.getMessage(), logCommit3.getMessage());
    ref = geogig.command(RefParse.class).setName(Ref.ORIG_HEAD).call();
    assertFalse(ref.isPresent());
}
Also used : AddOp(org.locationtech.geogig.api.porcelain.AddOp) ConflictsReadOp(org.locationtech.geogig.api.plumbing.merge.ConflictsReadOp) RebaseConflictsException(org.locationtech.geogig.api.porcelain.RebaseConflictsException) LogOp(org.locationtech.geogig.api.porcelain.LogOp) CommitOp(org.locationtech.geogig.api.porcelain.CommitOp) RevFeature(org.locationtech.geogig.api.RevFeature) Feature(org.opengis.feature.Feature) Ref(org.locationtech.geogig.api.Ref) SymRef(org.locationtech.geogig.api.SymRef) NodeRef(org.locationtech.geogig.api.NodeRef) Conflict(org.locationtech.geogig.api.plumbing.merge.Conflict) RefParse(org.locationtech.geogig.api.plumbing.RefParse) RevCommit(org.locationtech.geogig.api.RevCommit) Test(org.junit.Test)

Example 4 with RebaseConflictsException

use of org.locationtech.geogig.api.porcelain.RebaseConflictsException in project GeoGig by boundlessgeo.

the class RebaseOpTest method testRebaseAbort.

@Test
public void testRebaseAbort() throws Exception {
    // Create the following revision graph
    // o
    // |
    // o - Points 1,2 added
    // |\
    // | o - branch1 - Points 1 modifiedB, 2 removed, 3 added
    // |
    // o - Points 1 modified, 2 removed
    // |
    // o - master - HEAD - Lines 1 added
    insertAndAdd(points1, points2);
    RevCommit firstCommit = geogig.command(CommitOp.class).call();
    geogig.command(BranchCreateOp.class).setName("branch1").call();
    Feature points1Modified = feature(pointsType, idP1, "StringProp1_2", new Integer(1000), "POINT(1 1)");
    insert(points1Modified);
    delete(points2);
    geogig.command(AddOp.class).call();
    RevCommit masterCommit2 = geogig.command(CommitOp.class).setMessage("adding points1 modified, deleting point2").call();
    insert(lines1);
    geogig.command(AddOp.class).call();
    RevCommit masterCommit = geogig.command(CommitOp.class).setMessage("adding lines.1").call();
    geogig.command(CheckoutOp.class).setSource("branch1").call();
    insert(points3);
    Feature points1ModifiedB = feature(pointsType, idP1, "StringProp1_3", new Integer(2000), "POINT(1 1)");
    insert(points1ModifiedB);
    delete(points2);
    geogig.command(AddOp.class).call();
    geogig.command(CommitOp.class).setMessage("branch commit").call();
    geogig.command(CheckoutOp.class).setSource("master").call();
    Ref branch1 = geogig.command(RefParse.class).setName("branch1").call().get();
    try {
        geogig.command(RebaseOp.class).setUpstream(Suppliers.ofInstance(branch1.getObjectId())).call();
        fail();
    } catch (RebaseConflictsException e) {
        assertTrue(e.getMessage().contains("conflict"));
    }
    geogig.command(RebaseOp.class).setAbort(true).call();
    Optional<Ref> head = geogig.command(RefParse.class).setName(Ref.HEAD).call();
    assertTrue(head.isPresent());
    assertEquals(head.get().getObjectId(), masterCommit.getId());
    Iterator<RevCommit> log = geogig.command(LogOp.class).call();
    RevCommit logCommit1 = log.next();
    assertEquals(masterCommit.getMessage(), logCommit1.getMessage());
    RevCommit logCommit2 = log.next();
    assertEquals(masterCommit2.getMessage(), logCommit2.getMessage());
    RevCommit logCommit3 = log.next();
    assertEquals(firstCommit.getMessage(), logCommit3.getMessage());
    String path = NodeRef.appendChild(pointsName, idP1);
    Optional<RevFeature> points = geogig.command(RevObjectParse.class).setRefSpec(Ref.HEAD + ":" + path).call(RevFeature.class);
    assertTrue(points.isPresent());
    assertEquals(RevFeatureBuilder.build(points1Modified), points.get());
}
Also used : AddOp(org.locationtech.geogig.api.porcelain.AddOp) RebaseConflictsException(org.locationtech.geogig.api.porcelain.RebaseConflictsException) LogOp(org.locationtech.geogig.api.porcelain.LogOp) CommitOp(org.locationtech.geogig.api.porcelain.CommitOp) RevFeature(org.locationtech.geogig.api.RevFeature) Feature(org.opengis.feature.Feature) Ref(org.locationtech.geogig.api.Ref) SymRef(org.locationtech.geogig.api.SymRef) NodeRef(org.locationtech.geogig.api.NodeRef) RevFeature(org.locationtech.geogig.api.RevFeature) RefParse(org.locationtech.geogig.api.plumbing.RefParse) RevCommit(org.locationtech.geogig.api.RevCommit) Test(org.junit.Test)

Example 5 with RebaseConflictsException

use of org.locationtech.geogig.api.porcelain.RebaseConflictsException in project GeoGig by boundlessgeo.

the class TransactionEnd method updateRefs.

private void updateRefs() {
    final Optional<Ref> currHead = command(RefParse.class).setName(Ref.HEAD).call();
    final String currentBranch;
    if (currHead.isPresent() && currHead.get() instanceof SymRef) {
        currentBranch = ((SymRef) currHead.get()).getTarget();
    } else {
        currentBranch = "";
    }
    ImmutableSet<Ref> changedRefs = getChangedRefs();
    // Lock the repository
    try {
        refDatabase().lock();
    } catch (TimeoutException e) {
        Throwables.propagate(e);
    }
    try {
        // Update refs
        for (Ref ref : changedRefs) {
            if (!ref.getName().startsWith(Ref.REFS_PREFIX)) {
                continue;
            }
            Ref updatedRef = ref;
            Optional<Ref> repoRef = command(RefParse.class).setName(ref.getName()).call();
            if (repoRef.isPresent() && repositoryChanged(repoRef.get())) {
                if (rebase) {
                    // Try to rebase
                    transaction.command(CheckoutOp.class).setSource(ref.getName()).setForce(true).call();
                    try {
                        transaction.command(RebaseOp.class).setUpstream(Suppliers.ofInstance(repoRef.get().getObjectId())).call();
                    } catch (RebaseConflictsException e) {
                        Throwables.propagate(e);
                    }
                    updatedRef = transaction.command(RefParse.class).setName(ref.getName()).call().get();
                } else {
                    // sync transactions have to use merge to prevent divergent history
                    transaction.command(CheckoutOp.class).setSource(ref.getName()).setForce(true).call();
                    try {
                        transaction.command(MergeOp.class).setAuthor(authorName.orNull(), authorEmail.orNull()).addCommit(Suppliers.ofInstance(repoRef.get().getObjectId())).call();
                    } catch (NothingToCommitException e) {
                    // The repo commit is already in our history, this is a fast
                    // forward.
                    }
                    updatedRef = transaction.command(RefParse.class).setName(ref.getName()).call().get();
                }
            }
            LOGGER.debug(String.format("commit %s %s -> %s", ref.getName(), ref.getObjectId(), updatedRef.getObjectId()));
            command(UpdateRef.class).setName(ref.getName()).setNewValue(updatedRef.getObjectId()).call();
            if (currentBranch.equals(ref.getName())) {
                // Update HEAD, WORK_HEAD and STAGE_HEAD
                command(UpdateSymRef.class).setName(Ref.HEAD).setNewValue(ref.getName()).call();
                command(UpdateRef.class).setName(Ref.WORK_HEAD).setNewValue(updatedRef.getObjectId()).call();
                command(UpdateRef.class).setName(Ref.STAGE_HEAD).setNewValue(updatedRef.getObjectId()).call();
            }
        }
    // TODO: What happens if there are unstaged or staged changes in the repository when
    // a transaction is committed?
    } finally {
        // Unlock the repository
        refDatabase().unlock();
    }
}
Also used : Ref(org.locationtech.geogig.api.Ref) SymRef(org.locationtech.geogig.api.SymRef) SymRef(org.locationtech.geogig.api.SymRef) RebaseConflictsException(org.locationtech.geogig.api.porcelain.RebaseConflictsException) NothingToCommitException(org.locationtech.geogig.api.porcelain.NothingToCommitException) CheckoutOp(org.locationtech.geogig.api.porcelain.CheckoutOp) MergeOp(org.locationtech.geogig.api.porcelain.MergeOp) TimeoutException(java.util.concurrent.TimeoutException)

Aggregations

RebaseConflictsException (org.locationtech.geogig.api.porcelain.RebaseConflictsException)7 Ref (org.locationtech.geogig.api.Ref)6 RevCommit (org.locationtech.geogig.api.RevCommit)5 SymRef (org.locationtech.geogig.api.SymRef)5 Test (org.junit.Test)4 NodeRef (org.locationtech.geogig.api.NodeRef)4 RevFeature (org.locationtech.geogig.api.RevFeature)4 RefParse (org.locationtech.geogig.api.plumbing.RefParse)4 AddOp (org.locationtech.geogig.api.porcelain.AddOp)4 CommitOp (org.locationtech.geogig.api.porcelain.CommitOp)4 LogOp (org.locationtech.geogig.api.porcelain.LogOp)4 Feature (org.opengis.feature.Feature)4 Conflict (org.locationtech.geogig.api.plumbing.merge.Conflict)3 ConflictsReadOp (org.locationtech.geogig.api.plumbing.merge.ConflictsReadOp)3 RevObjectParse (org.locationtech.geogig.api.plumbing.RevObjectParse)2 RebaseOp (org.locationtech.geogig.api.porcelain.RebaseOp)2 Optional (com.google.common.base.Optional)1 TimeoutException (java.util.concurrent.TimeoutException)1 Context (org.locationtech.geogig.api.Context)1 GeoGIG (org.locationtech.geogig.api.GeoGIG)1