Search in sources :

Example 91 with NodeRef

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

the class TreeDifference method findChanges.

/**
     * Finds child refs that are named the same, point to different trees, but are not pure metadata
     * changes
     * 
     * @return a sorted map of old/new references to a trees that have changed, deepest paths first
     */
public SortedMap<NodeRef, NodeRef> findChanges() {
    SortedMap<String, MutableTree> leftEntries = leftTree.getChildrenAsMap();
    SortedMap<String, MutableTree> rightEntries = rightTree.getChildrenAsMap();
    final Map<NodeRef, NodeRef> pureMetadataChanges = findPureMetadataChanges();
    SortedMapDifference<String, MutableTree> difference;
    difference = difference(leftEntries, rightEntries);
    SortedMap<String, ValueDifference<MutableTree>> entriesDiffering;
    entriesDiffering = difference.entriesDiffering();
    SortedMap<NodeRef, NodeRef> matches = Maps.newTreeMap(MutableTree.DEEPEST_FIRST_COMPARATOR);
    for (Map.Entry<String, ValueDifference<MutableTree>> e : entriesDiffering.entrySet()) {
        String nodePath = e.getKey();
        String parentPath = NodeRef.parentPath(nodePath);
        ValueDifference<MutableTree> vd = e.getValue();
        MutableTree left = vd.leftValue();
        MutableTree right = vd.rightValue();
        NodeRef lref = new NodeRef(left.getNode(), parentPath, ObjectId.NULL);
        NodeRef rref = new NodeRef(right.getNode(), parentPath, ObjectId.NULL);
        if (!pureMetadataChanges.containsKey(lref)) {
            matches.put(lref, rref);
        }
    }
    return matches;
}
Also used : NodeRef(org.locationtech.geogig.api.NodeRef) ValueDifference(com.google.common.collect.MapDifference.ValueDifference) Maps.newHashMap(com.google.common.collect.Maps.newHashMap) Map(java.util.Map) SortedMap(java.util.SortedMap) Maps.newTreeMap(com.google.common.collect.Maps.newTreeMap)

Example 92 with NodeRef

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

the class VerifyPatchOp method _call.

/**
     * Executes the verify command
     * 
     * @return the result of checking if the patch can be applied
     */
protected VerifyPatchResults _call() throws RuntimeException {
    Preconditions.checkArgument(patch != null, "No patch file provided");
    Patch patch = reverse ? this.patch.reversed() : this.patch;
    Patch toApply = new Patch();
    Patch toReject = new Patch();
    for (RevFeatureType ft : patch.getFeatureTypes()) {
        toApply.addFeatureType(ft);
        toReject.addFeatureType(ft);
    }
    String path;
    Optional<RevObject> obj;
    List<FeatureDiff> diffs = patch.getModifiedFeatures();
    for (FeatureDiff diff : diffs) {
        path = diff.getPath();
        String refSpec = Ref.WORK_HEAD + ":" + path;
        obj = command(RevObjectParse.class).setRefSpec(refSpec).call();
        if (!obj.isPresent()) {
            toReject.addModifiedFeature(diff);
            break;
        }
        RevFeature feature = (RevFeature) obj.get();
        DepthSearch depthSearch = new DepthSearch(stagingDatabase());
        Optional<NodeRef> noderef = depthSearch.find(workingTree().getTree(), path);
        RevFeatureType featureType = command(RevObjectParse.class).setObjectId(noderef.get().getMetadataId()).call(RevFeatureType.class).get();
        ImmutableList<PropertyDescriptor> descriptors = featureType.sortedDescriptors();
        Set<Entry<PropertyDescriptor, AttributeDiff>> attrDiffs = diff.getDiffs().entrySet();
        boolean ok = true;
        for (Iterator<Entry<PropertyDescriptor, AttributeDiff>> iterator = attrDiffs.iterator(); iterator.hasNext(); ) {
            Entry<PropertyDescriptor, AttributeDiff> entry = iterator.next();
            AttributeDiff attrDiff = entry.getValue();
            PropertyDescriptor descriptor = entry.getKey();
            switch(attrDiff.getType()) {
                case ADDED:
                    if (descriptors.contains(descriptor)) {
                        ok = false;
                    }
                    break;
                case REMOVED:
                case MODIFIED:
                    if (!descriptors.contains(descriptor)) {
                        ok = false;
                        break;
                    }
                    for (int i = 0; i < descriptors.size(); i++) {
                        if (descriptors.get(i).equals(descriptor)) {
                            Optional<Object> value = feature.getValues().get(i);
                            if (!attrDiff.canBeAppliedOn(value)) {
                                ok = false;
                            }
                            break;
                        }
                    }
            }
        }
        if (!ok) {
            toReject.addModifiedFeature(diff);
        } else {
            toApply.addModifiedFeature(diff);
        }
    }
    List<FeatureInfo> added = patch.getAddedFeatures();
    for (FeatureInfo feature : added) {
        String refSpec = Ref.WORK_HEAD + ":" + feature.getPath();
        obj = command(RevObjectParse.class).setRefSpec(refSpec).call();
        if (obj.isPresent()) {
            toReject.addAddedFeature(feature.getPath(), feature.getFeature(), feature.getFeatureType());
        } else {
            toApply.addAddedFeature(feature.getPath(), feature.getFeature(), feature.getFeatureType());
        }
    }
    List<FeatureInfo> removed = patch.getRemovedFeatures();
    for (FeatureInfo feature : removed) {
        String refSpec = Ref.WORK_HEAD + ":" + feature.getPath();
        obj = command(RevObjectParse.class).setRefSpec(refSpec).call();
        if (!obj.isPresent()) {
            toReject.addRemovedFeature(feature.getPath(), feature.getFeature(), feature.getFeatureType());
        } else {
            RevFeature revFeature = (RevFeature) obj.get();
            DepthSearch depthSearch = new DepthSearch(stagingDatabase());
            Optional<NodeRef> noderef = depthSearch.find(workingTree().getTree(), feature.getPath());
            RevFeatureType revFeatureType = command(RevObjectParse.class).setObjectId(noderef.get().getMetadataId()).call(RevFeatureType.class).get();
            RevFeature patchRevFeature = RevFeatureBuilder.build(feature.getFeature());
            if (revFeature.equals(patchRevFeature) && revFeatureType.equals(feature.getFeatureType())) {
                toApply.addRemovedFeature(feature.getPath(), feature.getFeature(), feature.getFeatureType());
            } else {
                toReject.addRemovedFeature(feature.getPath(), feature.getFeature(), feature.getFeatureType());
            }
        }
    }
    ImmutableList<FeatureTypeDiff> alteredTrees = patch.getAlteredTrees();
    for (FeatureTypeDiff diff : alteredTrees) {
        DepthSearch depthSearch = new DepthSearch(stagingDatabase());
        Optional<NodeRef> noderef = depthSearch.find(workingTree().getTree(), diff.getPath());
        ObjectId metadataId = noderef.isPresent() ? noderef.get().getMetadataId() : ObjectId.NULL;
        if (Objects.equal(metadataId, diff.getOldFeatureType())) {
            toApply.addAlteredTree(diff);
        } else {
            toReject.addAlteredTree(diff);
        }
    }
    return new VerifyPatchResults(toApply, toReject);
}
Also used : FeatureInfo(org.locationtech.geogig.api.FeatureInfo) NodeRef(org.locationtech.geogig.api.NodeRef) Entry(java.util.Map.Entry) RevFeature(org.locationtech.geogig.api.RevFeature) RevFeatureType(org.locationtech.geogig.api.RevFeatureType) PropertyDescriptor(org.opengis.feature.type.PropertyDescriptor) RevObject(org.locationtech.geogig.api.RevObject) ObjectId(org.locationtech.geogig.api.ObjectId) DepthSearch(org.locationtech.geogig.repository.DepthSearch) RevObjectParse(org.locationtech.geogig.api.plumbing.RevObjectParse) RevObject(org.locationtech.geogig.api.RevObject)

Example 93 with NodeRef

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

the class ReportCommitConflictsOp method _call.

@Override
protected MergeScenarioReport _call() {
    MergeScenarioReport report = new MergeScenarioReport();
    ObjectId parentCommitId = ObjectId.NULL;
    if (commit.getParentIds().size() > 0) {
        parentCommitId = commit.getParentIds().get(0);
    }
    ObjectId parentTreeId = ObjectId.NULL;
    Repository repository = repository();
    if (repository.commitExists(parentCommitId)) {
        parentTreeId = repository.getCommit(parentCommitId).getTreeId();
    }
    // get changes
    Iterator<DiffEntry> diffs = command(DiffTree.class).setOldTree(parentTreeId).setNewTree(commit.getTreeId()).setReportTrees(true).call();
    while (diffs.hasNext()) {
        DiffEntry diff = diffs.next();
        String path = diff.oldPath() == null ? diff.newPath() : diff.oldPath();
        Optional<RevObject> obj = command(RevObjectParse.class).setRefSpec(Ref.HEAD + ":" + path).call();
        switch(diff.changeType()) {
            case ADDED:
                if (obj.isPresent()) {
                    TYPE type = command(ResolveObjectType.class).setObjectId(diff.getNewObject().objectId()).call();
                    if (TYPE.TREE.equals(type)) {
                        NodeRef headVersion = command(FindTreeChild.class).setChildPath(path).setParent(repository.getOrCreateHeadTree()).call().get();
                        if (!headVersion.getMetadataId().equals(diff.getNewObject().getMetadataId())) {
                            report.addConflict(new Conflict(path, ObjectId.NULL, diff.getNewObject().getMetadataId(), headVersion.getMetadataId()));
                        }
                    } else {
                        if (!obj.get().getId().equals(diff.newObjectId())) {
                            report.addConflict(new Conflict(path, ObjectId.NULL, diff.newObjectId(), obj.get().getId()));
                        }
                    }
                } else {
                    report.addUnconflicted(diff);
                }
                break;
            case REMOVED:
                if (obj.isPresent()) {
                    if (obj.get().getId().equals(diff.oldObjectId())) {
                        report.addUnconflicted(diff);
                    } else {
                        report.addConflict(new Conflict(path, diff.oldObjectId(), ObjectId.NULL, obj.get().getId()));
                    }
                }
                break;
            case MODIFIED:
                TYPE type = command(ResolveObjectType.class).setObjectId(diff.getNewObject().objectId()).call();
                if (TYPE.TREE.equals(type)) {
                    // one
                    if (!diff.isChange()) {
                        report.addUnconflicted(diff);
                    }
                } else {
                    String refSpec = Ref.HEAD + ":" + path;
                    obj = command(RevObjectParse.class).setRefSpec(refSpec).call();
                    if (!obj.isPresent()) {
                        // git reports this as a conflict but does not mark as conflicted, just adds
                        // the missing file.
                        // We add it and consider it unconflicted
                        report.addUnconflicted(diff);
                        break;
                    }
                    RevFeature feature = (RevFeature) obj.get();
                    DepthSearch depthSearch = new DepthSearch(repository.objectDatabase());
                    Optional<NodeRef> noderef = depthSearch.find(this.workingTree().getTree(), path);
                    RevFeatureType featureType = command(RevObjectParse.class).setObjectId(noderef.get().getMetadataId()).call(RevFeatureType.class).get();
                    ImmutableList<PropertyDescriptor> descriptors = featureType.sortedDescriptors();
                    FeatureDiff featureDiff = command(DiffFeature.class).setOldVersion(Suppliers.ofInstance(diff.getOldObject())).setNewVersion(Suppliers.ofInstance(diff.getNewObject())).call();
                    Set<Entry<PropertyDescriptor, AttributeDiff>> attrDiffs = featureDiff.getDiffs().entrySet();
                    RevFeature newFeature = command(RevObjectParse.class).setObjectId(diff.newObjectId()).call(RevFeature.class).get();
                    boolean ok = true;
                    for (Iterator<Entry<PropertyDescriptor, AttributeDiff>> iterator = attrDiffs.iterator(); iterator.hasNext() && ok; ) {
                        Entry<PropertyDescriptor, AttributeDiff> entry = iterator.next();
                        AttributeDiff attrDiff = entry.getValue();
                        PropertyDescriptor descriptor = entry.getKey();
                        switch(attrDiff.getType()) {
                            case ADDED:
                                if (descriptors.contains(descriptor)) {
                                    ok = false;
                                }
                                break;
                            case REMOVED:
                            case MODIFIED:
                                if (!descriptors.contains(descriptor)) {
                                    ok = false;
                                    break;
                                }
                                for (int i = 0; i < descriptors.size(); i++) {
                                    if (descriptors.get(i).equals(descriptor)) {
                                        Optional<Object> value = feature.getValues().get(i);
                                        Optional<Object> newValue = newFeature.getValues().get(i);
                                        if (!newValue.equals(value)) {
                                            // check
                                            if (!attrDiff.canBeAppliedOn(value)) {
                                                ok = false;
                                            }
                                            break;
                                        }
                                    }
                                }
                        }
                    }
                    if (ok) {
                        report.addUnconflicted(diff);
                    } else {
                        report.addConflict(new Conflict(path, diff.oldObjectId(), diff.newObjectId(), obj.get().getId()));
                    }
                }
                break;
        }
    }
    return report;
}
Also used : NodeRef(org.locationtech.geogig.api.NodeRef) FeatureDiff(org.locationtech.geogig.api.plumbing.diff.FeatureDiff) DiffEntry(org.locationtech.geogig.api.plumbing.diff.DiffEntry) Entry(java.util.Map.Entry) RevFeature(org.locationtech.geogig.api.RevFeature) AttributeDiff(org.locationtech.geogig.api.plumbing.diff.AttributeDiff) TYPE(org.locationtech.geogig.api.RevObject.TYPE) RevFeatureType(org.locationtech.geogig.api.RevFeatureType) DiffEntry(org.locationtech.geogig.api.plumbing.diff.DiffEntry) PropertyDescriptor(org.opengis.feature.type.PropertyDescriptor) ObjectId(org.locationtech.geogig.api.ObjectId) RevObject(org.locationtech.geogig.api.RevObject) DiffFeature(org.locationtech.geogig.api.plumbing.DiffFeature) Repository(org.locationtech.geogig.repository.Repository) DepthSearch(org.locationtech.geogig.repository.DepthSearch) RevObjectParse(org.locationtech.geogig.api.plumbing.RevObjectParse) RevObject(org.locationtech.geogig.api.RevObject)

Example 94 with NodeRef

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

the class ReportMergeScenarioOp method _call.

@Override
protected MergeScenarioReport _call() {
    Optional<ObjectId> ancestor = command(FindCommonAncestor.class).setLeft(toMerge).setRight(mergeInto).call();
    Preconditions.checkState(ancestor.isPresent(), "No ancestor commit could be found.");
    Map<String, DiffEntry> mergeIntoDiffs = Maps.newHashMap();
    MergeScenarioReport report = new MergeScenarioReport();
    Iterator<DiffEntry> diffs = command(DiffTree.class).setOldTree(ancestor.get()).setReportTrees(true).setNewTree(mergeInto.getId()).call();
    while (diffs.hasNext()) {
        DiffEntry diff = diffs.next();
        String path = diff.oldPath() == null ? diff.newPath() : diff.oldPath();
        mergeIntoDiffs.put(path, diff);
    }
    Iterator<DiffEntry> toMergeDiffs = command(DiffTree.class).setOldTree(ancestor.get()).setReportTrees(true).setNewTree(toMerge.getId()).call();
    while (toMergeDiffs.hasNext()) {
        DiffEntry toMergeDiff = toMergeDiffs.next();
        String path = toMergeDiff.oldPath() == null ? toMergeDiff.newPath() : toMergeDiff.oldPath();
        if (mergeIntoDiffs.containsKey(path)) {
            RevCommit ancestorCommit = command(RevObjectParse.class).setRefSpec(ancestor.get().toString()).call(RevCommit.class).get();
            RevTree ancestorTree = command(RevObjectParse.class).setObjectId(ancestorCommit.getTreeId()).call(RevTree.class).get();
            Optional<NodeRef> ancestorVersion = command(FindTreeChild.class).setChildPath(path).setParent(ancestorTree).call();
            ObjectId ancestorVersionId = ancestorVersion.isPresent() ? ancestorVersion.get().getNode().getObjectId() : ObjectId.NULL;
            ObjectId theirs = toMergeDiff.getNewObject() == null ? ObjectId.NULL : toMergeDiff.getNewObject().objectId();
            DiffEntry mergeIntoDiff = mergeIntoDiffs.get(path);
            ObjectId ours = mergeIntoDiff.getNewObject() == null ? ObjectId.NULL : mergeIntoDiff.getNewObject().objectId();
            if (!mergeIntoDiff.changeType().equals(toMergeDiff.changeType())) {
                report.addConflict(new Conflict(path, ancestorVersionId, ours, theirs));
                continue;
            }
            switch(toMergeDiff.changeType()) {
                case ADDED:
                    if (toMergeDiff.getNewObject().equals(mergeIntoDiff.getNewObject())) {
                    // already added in current branch, no need to do anything
                    } else {
                        TYPE type = command(ResolveObjectType.class).setObjectId(toMergeDiff.getNewObject().objectId()).call();
                        if (TYPE.TREE.equals(type)) {
                            boolean conflict = !toMergeDiff.getNewObject().getMetadataId().equals(mergeIntoDiff.getNewObject().getMetadataId());
                            if (conflict) {
                                // In this case, we store the metadata id, not the element id
                                ancestorVersionId = ancestorVersion.isPresent() ? ancestorVersion.get().getMetadataId() : ObjectId.NULL;
                                ours = mergeIntoDiff.getNewObject().getMetadataId();
                                theirs = toMergeDiff.getNewObject().getMetadataId();
                                report.addConflict(new Conflict(path, ancestorVersionId, ours, theirs));
                            }
                        // if the metadata ids match, it means both branches have added the same
                        // tree, maybe with different content, but there is no need to do
                        // anything. The correct tree is already there and the merge can be run
                        // safely, so we do not add it neither as a conflicted change nor as an
                        // unconflicted one
                        } else {
                            report.addConflict(new Conflict(path, ancestorVersionId, ours, theirs));
                        }
                    }
                    break;
                case REMOVED:
                    // removed by both histories => no conflict and no need to do anything
                    break;
                case MODIFIED:
                    TYPE type = command(ResolveObjectType.class).setObjectId(toMergeDiff.getNewObject().objectId()).call();
                    if (TYPE.TREE.equals(type)) {
                        boolean conflict = !toMergeDiff.getNewObject().getMetadataId().equals(mergeIntoDiff.getNewObject().getMetadataId());
                        if (conflict) {
                            // In this case, we store the metadata id, not the element id
                            ancestorVersionId = ancestorVersion.isPresent() ? ancestorVersion.get().getMetadataId() : ObjectId.NULL;
                            ours = mergeIntoDiff.getNewObject().getMetadataId();
                            theirs = toMergeDiff.getNewObject().getMetadataId();
                            report.addConflict(new Conflict(path, ancestorVersionId, ours, theirs));
                        }
                    } else {
                        FeatureDiff toMergeFeatureDiff = command(DiffFeature.class).setOldVersion(Suppliers.ofInstance(toMergeDiff.getOldObject())).setNewVersion(Suppliers.ofInstance(toMergeDiff.getNewObject())).call();
                        FeatureDiff mergeIntoFeatureDiff = command(DiffFeature.class).setOldVersion(Suppliers.ofInstance(mergeIntoDiff.getOldObject())).setNewVersion(Suppliers.ofInstance(mergeIntoDiff.getNewObject())).call();
                        if (toMergeFeatureDiff.conflicts(mergeIntoFeatureDiff)) {
                            report.addConflict(new Conflict(path, ancestorVersionId, ours, theirs));
                        } else {
                            // try to perform automerge
                            if (!toMergeDiff.getNewObject().getMetadataId().equals(mergeIntoDiff.getNewObject().getMetadataId())) {
                                report.addConflict(new Conflict(path, ancestorVersionId, ours, theirs));
                            } else if (!toMergeFeatureDiff.equals(mergeIntoFeatureDiff)) {
                                Feature mergedFeature = command(MergeFeaturesOp.class).setFirstFeature(mergeIntoDiff.getNewObject()).setSecondFeature(toMergeDiff.getNewObject()).setAncestorFeature(mergeIntoDiff.getOldObject()).call();
                                RevFeature revFeature = RevFeatureBuilder.build(mergedFeature);
                                if (revFeature.getId().equals(toMergeDiff.newObjectId())) {
                                    // the resulting merged feature equals the feature to merge from
                                    // the branch, which means that it exists in the repo and there
                                    // is no need to add it
                                    report.addUnconflicted(toMergeDiff);
                                } else {
                                    RevFeatureType featureType = command(RevObjectParse.class).setObjectId(mergeIntoDiff.getNewObject().getMetadataId()).call(RevFeatureType.class).get();
                                    FeatureInfo merged = new FeatureInfo(mergedFeature, featureType, path);
                                    report.addMerged(merged);
                                }
                            }
                        }
                    }
                    break;
            }
        } else {
            // modified in the other branch under it.
            if (ChangeType.REMOVED.equals(toMergeDiff.changeType())) {
                TYPE type = command(ResolveObjectType.class).setObjectId(toMergeDiff.oldObjectId()).call();
                if (TYPE.TREE.equals(type)) {
                    String parentPath = toMergeDiff.oldPath();
                    Set<Entry<String, DiffEntry>> entries = mergeIntoDiffs.entrySet();
                    boolean conflict = false;
                    for (Entry<String, DiffEntry> entry : entries) {
                        if (entry.getKey().startsWith(parentPath)) {
                            if (!ChangeType.REMOVED.equals(entry.getValue().changeType())) {
                                RevCommit ancestorCommit = command(RevObjectParse.class).setRefSpec(ancestor.get().toString()).call(RevCommit.class).get();
                                RevTree ancestorTree = command(RevObjectParse.class).setObjectId(ancestorCommit.getTreeId()).call(RevTree.class).get();
                                Optional<NodeRef> ancestorVersion = command(FindTreeChild.class).setChildPath(path).setParent(ancestorTree).call();
                                ObjectId ancestorVersionId = ancestorVersion.isPresent() ? ancestorVersion.get().getNode().getObjectId() : ObjectId.NULL;
                                ObjectId theirs = toMergeDiff.getNewObject() == null ? ObjectId.NULL : toMergeDiff.getNewObject().objectId();
                                String oursRefSpec = mergeInto.getId().toString() + ":" + parentPath;
                                Optional<ObjectId> ours = command(RevParse.class).setRefSpec(oursRefSpec).call();
                                report.addConflict(new Conflict(path, ancestorVersionId, ours.get(), theirs));
                                conflict = true;
                                break;
                            }
                        }
                    }
                    if (!conflict) {
                        report.addUnconflicted(toMergeDiff);
                    }
                } else {
                    report.addUnconflicted(toMergeDiff);
                }
            } else {
                report.addUnconflicted(toMergeDiff);
            }
        }
    }
    return report;
}
Also used : FeatureInfo(org.locationtech.geogig.api.FeatureInfo) RevFeature(org.locationtech.geogig.api.RevFeature) DiffFeature(org.locationtech.geogig.api.plumbing.DiffFeature) Feature(org.opengis.feature.Feature) NodeRef(org.locationtech.geogig.api.NodeRef) FeatureDiff(org.locationtech.geogig.api.plumbing.diff.FeatureDiff) DiffEntry(org.locationtech.geogig.api.plumbing.diff.DiffEntry) Entry(java.util.Map.Entry) RevFeature(org.locationtech.geogig.api.RevFeature) TYPE(org.locationtech.geogig.api.RevObject.TYPE) RevFeatureType(org.locationtech.geogig.api.RevFeatureType) DiffEntry(org.locationtech.geogig.api.plumbing.diff.DiffEntry) RevCommit(org.locationtech.geogig.api.RevCommit) ObjectId(org.locationtech.geogig.api.ObjectId) DiffFeature(org.locationtech.geogig.api.plumbing.DiffFeature) FindTreeChild(org.locationtech.geogig.api.plumbing.FindTreeChild) FindCommonAncestor(org.locationtech.geogig.api.plumbing.FindCommonAncestor) RevObjectParse(org.locationtech.geogig.api.plumbing.RevObjectParse) RevTree(org.locationtech.geogig.api.RevTree)

Example 95 with NodeRef

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

the class TreeDifference method findNewTrees.

/**
     * Finds child refs that exist on the right root tree, don't exist on the left root tree, and
     * are not renames.
     * 
     * @return
     */
public SortedSet<NodeRef> findNewTrees() {
    SortedMap<String, MutableTree> leftEntries = leftTree.getChildrenAsMap();
    SortedMap<String, MutableTree> rightEntries = rightTree.getChildrenAsMap();
    SortedMapDifference<String, MutableTree> difference;
    difference = difference(leftEntries, rightEntries);
    Map<String, MutableTree> entriesOnlyOnRight;
    entriesOnlyOnRight = newHashMap(difference.entriesOnlyOnRight());
    // ignore renames
    Map<NodeRef, NodeRef> pureRenames = findRenames(difference);
    for (NodeRef renamedTo : pureRenames.values()) {
        entriesOnlyOnRight.remove(renamedTo.path());
    }
    SortedSet<NodeRef> newTreeRefs = Sets.newTreeSet();
    for (Map.Entry<String, MutableTree> newTree : entriesOnlyOnRight.entrySet()) {
        Node node = newTree.getValue().getNode();
        String parentPath = NodeRef.parentPath(newTree.getKey());
        // pass NULL to the NodeRef metadataId, to it defers to the one in the Node in case it
        // has one (see NodeRef.getMetadataId())
        ObjectId metadataId = ObjectId.NULL;
        NodeRef ref = new NodeRef(node, parentPath, metadataId);
        newTreeRefs.add(ref);
    }
    return newTreeRefs;
}
Also used : NodeRef(org.locationtech.geogig.api.NodeRef) ObjectId(org.locationtech.geogig.api.ObjectId) Node(org.locationtech.geogig.api.Node) Maps.newHashMap(com.google.common.collect.Maps.newHashMap) Map(java.util.Map) SortedMap(java.util.SortedMap) Maps.newTreeMap(com.google.common.collect.Maps.newTreeMap)

Aggregations

NodeRef (org.locationtech.geogig.api.NodeRef)161 ObjectId (org.locationtech.geogig.api.ObjectId)91 RevTree (org.locationtech.geogig.api.RevTree)67 Test (org.junit.Test)62 RevFeatureType (org.locationtech.geogig.api.RevFeatureType)40 RevObjectParse (org.locationtech.geogig.api.plumbing.RevObjectParse)27 RevFeature (org.locationtech.geogig.api.RevFeature)25 Node (org.locationtech.geogig.api.Node)24 RevTreeBuilder (org.locationtech.geogig.api.RevTreeBuilder)24 DiffEntry (org.locationtech.geogig.api.plumbing.diff.DiffEntry)23 FindTreeChild (org.locationtech.geogig.api.plumbing.FindTreeChild)22 RevObject (org.locationtech.geogig.api.RevObject)21 RevCommit (org.locationtech.geogig.api.RevCommit)19 Map (java.util.Map)15 SimpleFeature (org.opengis.feature.simple.SimpleFeature)15 SimpleFeatureType (org.opengis.feature.simple.SimpleFeatureType)14 Feature (org.opengis.feature.Feature)13 Optional (com.google.common.base.Optional)12 GeoGIG (org.locationtech.geogig.api.GeoGIG)11 LsTreeOp (org.locationtech.geogig.api.plumbing.LsTreeOp)11