Search in sources :

Example 11 with Conflict

use of org.locationtech.geogig.api.plumbing.merge.Conflict in project GeoGig by boundlessgeo.

the class ResetOpTest method testResetPathToHeadVersionFixesConflict.

@Test
public void testResetPathToHeadVersionFixesConflict() throws Exception {
    Feature points1Modified = feature(pointsType, idP1, "StringProp1_2", new Integer(1000), "POINT(1 1)");
    Feature points1ModifiedB = feature(pointsType, idP1, "StringProp1_3", new Integer(2000), "POINT(1 1)");
    insertAndAdd(points1);
    geogig.command(CommitOp.class).call();
    geogig.command(BranchCreateOp.class).setName("TestBranch").call();
    insertAndAdd(points1Modified);
    geogig.command(CommitOp.class).call();
    geogig.command(CheckoutOp.class).setSource("TestBranch").call();
    insertAndAdd(points1ModifiedB);
    insertAndAdd(points2);
    geogig.command(CommitOp.class).call();
    geogig.command(CheckoutOp.class).setSource("master").call();
    Ref branch = geogig.command(RefParse.class).setName("TestBranch").call().get();
    try {
        geogig.command(MergeOp.class).addCommit(Suppliers.ofInstance(branch.getObjectId())).call();
        fail();
    } catch (MergeConflictsException e) {
        assertTrue(e.getMessage().contains("conflict"));
    }
    geogig.command(ResetOp.class).addPattern(pointsName + "/" + idP1).call();
    List<Conflict> conflicts = geogig.getRepository().stagingDatabase().getConflicts(null, null);
    assertTrue(conflicts.isEmpty());
}
Also used : Ref(org.locationtech.geogig.api.Ref) MergeConflictsException(org.locationtech.geogig.api.porcelain.MergeConflictsException) Conflict(org.locationtech.geogig.api.plumbing.merge.Conflict) RefParse(org.locationtech.geogig.api.plumbing.RefParse) CommitOp(org.locationtech.geogig.api.porcelain.CommitOp) Feature(org.opengis.feature.Feature) Test(org.junit.Test)

Example 12 with Conflict

use of org.locationtech.geogig.api.plumbing.merge.Conflict in project GeoGig by boundlessgeo.

the class ResetOpTest method testResetPathFixesConflict.

@Test
public void testResetPathFixesConflict() throws Exception {
    Feature points1Modified = feature(pointsType, idP1, "StringProp1_2", new Integer(1000), "POINT(1 1)");
    Feature points1ModifiedB = feature(pointsType, idP1, "StringProp1_3", new Integer(2000), "POINT(1 1)");
    insertAndAdd(points1);
    RevCommit resetCommit = geogig.command(CommitOp.class).call();
    geogig.command(BranchCreateOp.class).setName("TestBranch").call();
    insertAndAdd(points1Modified);
    geogig.command(CommitOp.class).call();
    geogig.command(CheckoutOp.class).setSource("TestBranch").call();
    insertAndAdd(points1ModifiedB);
    insertAndAdd(points2);
    geogig.command(CommitOp.class).call();
    geogig.command(CheckoutOp.class).setSource("master").call();
    Ref branch = geogig.command(RefParse.class).setName("TestBranch").call().get();
    try {
        geogig.command(MergeOp.class).addCommit(Suppliers.ofInstance(branch.getObjectId())).call();
        fail();
    } catch (MergeConflictsException e) {
        assertTrue(e.getMessage().contains("conflict"));
    }
    geogig.command(ResetOp.class).addPattern(pointsName + "/" + idP1).setCommit(Suppliers.ofInstance(resetCommit.getId())).call();
    List<Conflict> conflicts = geogig.getRepository().stagingDatabase().getConflicts(null, null);
    assertTrue(conflicts.isEmpty());
}
Also used : Ref(org.locationtech.geogig.api.Ref) MergeConflictsException(org.locationtech.geogig.api.porcelain.MergeConflictsException) Conflict(org.locationtech.geogig.api.plumbing.merge.Conflict) RefParse(org.locationtech.geogig.api.plumbing.RefParse) CommitOp(org.locationtech.geogig.api.porcelain.CommitOp) ResetOp(org.locationtech.geogig.api.porcelain.ResetOp) Feature(org.opengis.feature.Feature) RevCommit(org.locationtech.geogig.api.RevCommit) Test(org.junit.Test)

Example 13 with Conflict

use of org.locationtech.geogig.api.plumbing.merge.Conflict 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 14 with Conflict

use of org.locationtech.geogig.api.plumbing.merge.Conflict in project GeoGig by boundlessgeo.

the class JEStagingDatabase method getConflict.

/**
     * Gets the specified conflict from the database.
     * 
     * @param namespace the namespace of the conflict
     * @param path the conflict to retrieve
     * @return the conflict, or {@link Optional#absent()} if it was not found
     */
@Override
public Optional<Conflict> getConflict(@Nullable String namespace, final String path) {
    final Object monitor = resolveConflictsMonitor(namespace);
    if (null == monitor) {
        return Optional.absent();
    }
    synchronized (monitor) {
        File file = resolveConflictsFile(namespace);
        if (file == null || !file.exists()) {
            return Optional.absent();
        }
        Conflict conflict = null;
        try {
            conflict = Files.readLines(file, Charsets.UTF_8, new LineProcessor<Conflict>() {

                Conflict conflict = null;

                @Override
                public Conflict getResult() {
                    return conflict;
                }

                @Override
                public boolean processLine(String s) throws IOException {
                    Conflict c = Conflict.valueOf(s);
                    if (c.getPath().equals(path)) {
                        conflict = c;
                        return false;
                    } else {
                        return true;
                    }
                }
            });
        } catch (IOException e) {
            throw Throwables.propagate(e);
        }
        return Optional.fromNullable(conflict);
    }
}
Also used : Conflict(org.locationtech.geogig.api.plumbing.merge.Conflict) IOException(java.io.IOException) LineProcessor(com.google.common.io.LineProcessor) File(java.io.File)

Example 15 with Conflict

use of org.locationtech.geogig.api.plumbing.merge.Conflict in project GeoGig by boundlessgeo.

the class CheckoutOp method _call.

/**
     * @return the id of the new work tree
     */
@Override
protected CheckoutResult _call() {
    checkState(branchOrCommit != null || !paths.isEmpty(), "No branch, tree, or path were specified");
    checkArgument(!(ours && theirs), "Cannot use both --ours and --theirs.");
    checkArgument((ours == theirs) || branchOrCommit == null, "--ours/--theirs is incompatible with switching branches.");
    CheckoutResult result = new CheckoutResult();
    List<Conflict> conflicts = stagingDatabase().getConflicts(null, null);
    if (!paths.isEmpty()) {
        result.setResult(CheckoutResult.Results.UPDATE_OBJECTS);
        Optional<RevTree> tree = Optional.absent();
        List<String> unmerged = lookForUnmerged(conflicts, paths);
        if (!unmerged.isEmpty()) {
            if (!(force || ours || theirs)) {
                StringBuilder msg = new StringBuilder();
                for (String path : unmerged) {
                    msg.append("error: path " + path + " is unmerged.\n");
                }
                throw new CheckoutException(msg.toString(), StatusCode.UNMERGED_PATHS);
            }
        }
        if (branchOrCommit != null) {
            Optional<ObjectId> id = command(ResolveTreeish.class).setTreeish(branchOrCommit).call();
            checkState(id.isPresent(), "'" + branchOrCommit + "' not found in repository.");
            tree = command(RevObjectParse.class).setObjectId(id.get()).call(RevTree.class);
        } else {
            tree = Optional.of(index().getTree());
        }
        Optional<RevTree> mainTree = tree;
        for (String st : paths) {
            if (unmerged.contains(st)) {
                if (ours || theirs) {
                    String refspec = ours ? Ref.ORIG_HEAD : Ref.MERGE_HEAD;
                    Optional<ObjectId> treeId = command(ResolveTreeish.class).setTreeish(refspec).call();
                    if (treeId.isPresent()) {
                        tree = command(RevObjectParse.class).setObjectId(treeId.get()).call(RevTree.class);
                    }
                } else {
                    // --force
                    continue;
                }
            } else {
                tree = mainTree;
            }
            Optional<NodeRef> node = command(FindTreeChild.class).setParent(tree.get()).setIndex(true).setChildPath(st).call();
            if ((ours || theirs) && !node.isPresent()) {
                // remove the node.
                command(RemoveOp.class).addPathToRemove(st).call();
            } else {
                checkState(node.isPresent(), "pathspec '" + st + "' didn't match a feature in the tree");
                if (node.get().getType() == TYPE.TREE) {
                    RevTreeBuilder treeBuilder = new RevTreeBuilder(stagingDatabase(), workingTree().getTree());
                    treeBuilder.remove(st);
                    treeBuilder.put(node.get().getNode());
                    RevTree newRoot = treeBuilder.build();
                    stagingDatabase().put(newRoot);
                    workingTree().updateWorkHead(newRoot.getId());
                } else {
                    ObjectId metadataId = ObjectId.NULL;
                    Optional<NodeRef> parentNode = command(FindTreeChild.class).setParent(workingTree().getTree()).setChildPath(node.get().getParentPath()).setIndex(true).call();
                    RevTreeBuilder treeBuilder = null;
                    if (parentNode.isPresent()) {
                        metadataId = parentNode.get().getMetadataId();
                        Optional<RevTree> parsed = command(RevObjectParse.class).setObjectId(parentNode.get().getNode().getObjectId()).call(RevTree.class);
                        checkState(parsed.isPresent(), "Parent tree couldn't be found in the repository.");
                        treeBuilder = new RevTreeBuilder(stagingDatabase(), parsed.get());
                        treeBuilder.remove(node.get().getNode().getName());
                    } else {
                        treeBuilder = new RevTreeBuilder(stagingDatabase());
                    }
                    treeBuilder.put(node.get().getNode());
                    ObjectId newTreeId = command(WriteBack.class).setAncestor(workingTree().getTree().builder(stagingDatabase())).setChildPath(node.get().getParentPath()).setToIndex(true).setTree(treeBuilder.build()).setMetadataId(metadataId).call();
                    workingTree().updateWorkHead(newTreeId);
                }
            }
        }
    } else {
        if (!conflicts.isEmpty()) {
            if (!(force)) {
                StringBuilder msg = new StringBuilder();
                for (Conflict conflict : conflicts) {
                    msg.append("error: " + conflict.getPath() + " needs merge.\n");
                }
                msg.append("You need to resolve your index first.\n");
                throw new CheckoutException(msg.toString(), StatusCode.UNMERGED_PATHS);
            }
        }
        Optional<Ref> targetRef = Optional.absent();
        Optional<ObjectId> targetCommitId = Optional.absent();
        Optional<ObjectId> targetTreeId = Optional.absent();
        targetRef = command(RefParse.class).setName(branchOrCommit).call();
        if (targetRef.isPresent()) {
            ObjectId commitId = targetRef.get().getObjectId();
            if (targetRef.get().getName().startsWith(Ref.REMOTES_PREFIX)) {
                String remoteName = targetRef.get().getName();
                remoteName = remoteName.substring(Ref.REMOTES_PREFIX.length(), targetRef.get().getName().lastIndexOf("/"));
                if (branchOrCommit.contains(remoteName + '/')) {
                    RevCommit commit = command(RevObjectParse.class).setObjectId(commitId).call(RevCommit.class).get();
                    targetTreeId = Optional.of(commit.getTreeId());
                    targetCommitId = Optional.of(commit.getId());
                    targetRef = Optional.absent();
                } else {
                    Ref branch = command(BranchCreateOp.class).setName(targetRef.get().localName()).setSource(commitId.toString()).call();
                    command(ConfigOp.class).setAction(ConfigAction.CONFIG_SET).setScope(ConfigScope.LOCAL).setName("branches." + branch.localName() + ".remote").setValue(remoteName).call();
                    command(ConfigOp.class).setAction(ConfigAction.CONFIG_SET).setScope(ConfigScope.LOCAL).setName("branches." + branch.localName() + ".merge").setValue(targetRef.get().getName()).call();
                    targetRef = Optional.of(branch);
                    result.setResult(CheckoutResult.Results.CHECKOUT_REMOTE_BRANCH);
                    result.setRemoteName(remoteName);
                }
            }
            if (commitId.isNull()) {
                targetTreeId = Optional.of(ObjectId.NULL);
                targetCommitId = Optional.of(ObjectId.NULL);
            } else {
                Optional<RevCommit> parsed = command(RevObjectParse.class).setObjectId(commitId).call(RevCommit.class);
                checkState(parsed.isPresent());
                checkState(parsed.get() instanceof RevCommit);
                RevCommit commit = parsed.get();
                targetCommitId = Optional.of(commit.getId());
                targetTreeId = Optional.of(commit.getTreeId());
            }
        } else {
            final Optional<ObjectId> addressed = command(RevParse.class).setRefSpec(branchOrCommit).call();
            checkArgument(addressed.isPresent(), "source '" + branchOrCommit + "' not found in repository");
            RevCommit commit = command(RevObjectParse.class).setObjectId(addressed.get()).call(RevCommit.class).get();
            targetTreeId = Optional.of(commit.getTreeId());
            targetCommitId = Optional.of(commit.getId());
        }
        if (targetTreeId.isPresent()) {
            if (!force) {
                if (!index().isClean() || !workingTree().isClean()) {
                    throw new CheckoutException(StatusCode.LOCAL_CHANGES_NOT_COMMITTED);
                }
            }
            // update work tree
            ObjectId treeId = targetTreeId.get();
            workingTree().updateWorkHead(treeId);
            index().updateStageHead(treeId);
            result.setNewTree(treeId);
            if (targetRef.isPresent()) {
                // update HEAD
                Ref target = targetRef.get();
                String refName;
                if (target instanceof SymRef) {
                    // beware of cyclic refs, peel symrefs
                    refName = ((SymRef) target).getTarget();
                } else {
                    refName = target.getName();
                }
                command(UpdateSymRef.class).setName(Ref.HEAD).setNewValue(refName).call();
                result.setNewRef(targetRef.get());
                result.setOid(targetCommitId.get());
                result.setResult(CheckoutResult.Results.CHECKOUT_LOCAL_BRANCH);
            } else {
                // set HEAD to a dettached state
                ObjectId commitId = targetCommitId.get();
                command(UpdateRef.class).setName(Ref.HEAD).setNewValue(commitId).call();
                result.setOid(commitId);
                result.setResult(CheckoutResult.Results.DETACHED_HEAD);
            }
            Optional<Ref> ref = command(RefParse.class).setName(Ref.MERGE_HEAD).call();
            if (ref.isPresent()) {
                command(UpdateRef.class).setName(Ref.MERGE_HEAD).setDelete(true).call();
            }
            return result;
        }
    }
    result.setNewTree(workingTree().getTree().getId());
    return result;
}
Also used : NodeRef(org.locationtech.geogig.api.NodeRef) UpdateSymRef(org.locationtech.geogig.api.plumbing.UpdateSymRef) UpdateSymRef(org.locationtech.geogig.api.plumbing.UpdateSymRef) SymRef(org.locationtech.geogig.api.SymRef) RefParse(org.locationtech.geogig.api.plumbing.RefParse) RevCommit(org.locationtech.geogig.api.RevCommit) ObjectId(org.locationtech.geogig.api.ObjectId) UpdateRef(org.locationtech.geogig.api.plumbing.UpdateRef) RevTreeBuilder(org.locationtech.geogig.api.RevTreeBuilder) UpdateRef(org.locationtech.geogig.api.plumbing.UpdateRef) UpdateSymRef(org.locationtech.geogig.api.plumbing.UpdateSymRef) 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) CanRunDuringConflict(org.locationtech.geogig.di.CanRunDuringConflict) RevObjectParse(org.locationtech.geogig.api.plumbing.RevObjectParse) RevTree(org.locationtech.geogig.api.RevTree)

Aggregations

Conflict (org.locationtech.geogig.api.plumbing.merge.Conflict)36 Ref (org.locationtech.geogig.api.Ref)17 RevCommit (org.locationtech.geogig.api.RevCommit)17 Test (org.junit.Test)16 NodeRef (org.locationtech.geogig.api.NodeRef)14 ObjectId (org.locationtech.geogig.api.ObjectId)14 ConflictsReadOp (org.locationtech.geogig.api.plumbing.merge.ConflictsReadOp)12 Feature (org.opengis.feature.Feature)12 RefParse (org.locationtech.geogig.api.plumbing.RefParse)11 CommitOp (org.locationtech.geogig.api.porcelain.CommitOp)10 SymRef (org.locationtech.geogig.api.SymRef)8 UpdateRef (org.locationtech.geogig.api.plumbing.UpdateRef)8 AddOp (org.locationtech.geogig.api.porcelain.AddOp)8 CanRunDuringConflict (org.locationtech.geogig.di.CanRunDuringConflict)8 MergeConflictsException (org.locationtech.geogig.api.porcelain.MergeConflictsException)7 File (java.io.File)6 IOException (java.io.IOException)6 UpdateSymRef (org.locationtech.geogig.api.plumbing.UpdateSymRef)6 DiffEntry (org.locationtech.geogig.api.plumbing.diff.DiffEntry)6 Repository (org.locationtech.geogig.repository.Repository)6