Index: oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernel.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernel.java (date 1395259799000) +++ oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernel.java (revision ) @@ -526,8 +526,9 @@ *
A property has been changed while a property of the same name has been changed to a * different value in trunk.
*
addExistingNode:
- *
A node has been added that is different from a node of them same name that has been added - * to the trunk.
+ *
A node has been added that can't be merged with a node of them same name that has + * been added to the trunk. How and whether merging takes place is up to the + * implementation. Merging must not cause data to be lost however.
*
deleteDeletedNode:
*
A node has been removed while a node of the same name has been removed in trunk.
*
deleteChangedNode:
Index: oak-core/src/test/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiffTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/test/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiffTest.java (date 1395259799000) +++ oak-core/src/test/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiffTest.java (revision ) @@ -155,21 +155,93 @@ public void addExistingNode() { NodeBuilder headBuilder = base.builder(); headBuilder.setChildNode("n"); - headBuilder.setChildNode("m"); + headBuilder.setChildNode("m").setChildNode("m1"); + headBuilder.getChildNode("m").setProperty("a", 1); + headBuilder.getChildNode("m").setProperty("p", 1); + headBuilder.getChildNode("m").setChildNode("mm").setChildNode("mm1"); NodeState head = headBuilder.getNodeState(); NodeBuilder branchBuilder = base.builder(); branchBuilder.setChildNode("n"); - branchBuilder.setChildNode("m").setChildNode("mm"); + branchBuilder.setChildNode("m").setChildNode("m2"); + branchBuilder.getChildNode("m").setProperty("a", 1); + branchBuilder.getChildNode("m").setProperty("q", 1); + branchBuilder.getChildNode("m").setChildNode("mm").setChildNode("mm2"); NodeState branch = branchBuilder.getNodeState(); - RebaseDiff rebaseDiff = new RebaseDiff(head.builder()) { + NodeBuilder builder = head.builder(); + RebaseDiff rebaseDiff = new RebaseDiff(builder); + branch.compareAgainstBaseState(base, rebaseDiff); + + NodeBuilder expectedBuilder = base.builder(); + expectedBuilder.setChildNode("n"); + expectedBuilder.setChildNode("n"); + expectedBuilder.setChildNode("m").setChildNode("m1"); + expectedBuilder.getChildNode("m").setChildNode("m2"); + expectedBuilder.getChildNode("m").setProperty("a", 1); + expectedBuilder.getChildNode("m").setProperty("p", 1); + expectedBuilder.getChildNode("m").setProperty("q", 1); + expectedBuilder.getChildNode("m").setChildNode("mm").setChildNode("mm1"); + expectedBuilder.getChildNode("m").getChildNode("mm").setChildNode("mm2"); + + assertEquals(expectedBuilder.getNodeState(), builder.getNodeState()); + } + + @Test + public void addExistingNodeWithConflict() { + NodeBuilder headBuilder = base.builder(); + headBuilder.setChildNode("n"); + headBuilder.setChildNode("m").setChildNode("m1"); + headBuilder.getChildNode("m").setProperty("p", 1); + headBuilder.getChildNode("m").setChildNode("mm").setChildNode("mmm").setProperty("pp", 1); + NodeState head = headBuilder.getNodeState(); + + NodeBuilder branchBuilder = base.builder(); + branchBuilder.setChildNode("n"); + branchBuilder.setChildNode("m").setChildNode("m2"); + branchBuilder.getChildNode("m").setProperty("q", 1); + branchBuilder.getChildNode("m").setChildNode("mm").setChildNode("mmm").setProperty("pp", 2); + NodeState branch = branchBuilder.getNodeState(); + + NodeBuilder builder = head.builder(); + + class ConflictResolver extends RebaseDiff { + private final ConflictResolver parent; + + private ConflictResolver(NodeBuilder builder) { + this(null, builder); + } + + public ConflictResolver(ConflictResolver parent, NodeBuilder builder) { + super(builder); + this.parent = parent; + } + @Override - protected void addExistingNode(NodeBuilder builder, String name, NodeState before, NodeState after) { - assertEquals("m", name); + protected void resolve() { + if (parent == null) { + super.resolve(); + } else { + parent.resolve(); + } + } + + @Override + protected AbstractRebaseDiff createDiff(NodeBuilder builder, String name) { + return new ConflictResolver( + this, builder.getChildNode(name)); + } + + @Override + protected void addExistingProperty(NodeBuilder builder, + PropertyState before, PropertyState after) { + assertEquals(createProperty("pp", 1), before); + assertEquals(createProperty("pp", 2), after); resolve(); } - }; + } + + RebaseDiff rebaseDiff = new ConflictResolver(builder); branch.compareAgainstBaseState(base, rebaseDiff); assertTrue(rebaseDiff.isResolved()); } @@ -256,7 +328,7 @@ @Override protected AbstractRebaseDiff createDiff(NodeBuilder builder, String name) { - return this; + return new RebaseDiff(builder.getChildNode(name)); } @Override Index: oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java (date 1395259799000) +++ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java (revision ) @@ -1602,8 +1602,8 @@ Session session1 = createAdminSession(); Session session2 = createAdminSession(); try { - session1.getRootNode().addNode("node"); - session2.getRootNode().addNode("node").setProperty("p", "v"); + session1.getRootNode().addNode("node").setProperty("p", "v1"); + session2.getRootNode().addNode("node").setProperty("p", "v2"); assertTrue(session1.getRootNode().hasNode("node")); assertTrue(session2.getRootNode().hasNode("node")); Index: oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java (date 1395259799000) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java (revision ) @@ -19,6 +19,8 @@ package org.apache.jackrabbit.oak.spi.state; +import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE; + import org.apache.jackrabbit.oak.api.PropertyState; /** @@ -204,10 +206,7 @@ @Override public boolean childNodeAdded(String name, NodeState after) { if (builder.hasChildNode(name)) { - NodeState other = builder.child(name).getNodeState(); - if (!other.equals(after)) { - addExistingNode(builder, name, other, after); - } + after.compareAgainstBaseState(EMPTY_NODE, createDiff(builder, name)); } else { builder.setChildNode(name, after); } @@ -215,8 +214,7 @@ } @Override - public boolean childNodeChanged( - String name, NodeState before, NodeState after) { + public boolean childNodeChanged(String name, NodeState before, NodeState after) { if (builder.hasChildNode(name)) { after.compareAgainstBaseState(before, createDiff(builder, name)); } else if (after.equals(before)) {