Author: mreutegg
Date: Tue Jan 19 15:02:57 2016
New Revision: 1725542
URL: http://svn.apache.org/viewvc?rev=1725542&view=rev
Log:
OAK-3897: Branch reset does not revert all changes
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ResetDiff.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentMKResetTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java?rev=1725542&r1=1725541&r2=1725542&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
Tue Jan 19 15:02:57 2016
@@ -335,7 +335,7 @@ public class DocumentMK {
throw new DocumentStoreException("Not a branch revision: " +
ancestorRevisionId);
}
try {
- return nodeStore.reset(branch, ancestor, null).toString();
+ return nodeStore.reset(branch, ancestor).toString();
} catch (DocumentStoreException e) {
throw new DocumentStoreException(e);
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1725542&r1=1725541&r2=1725542&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
Tue Jan 19 15:02:57 2016
@@ -22,6 +22,8 @@ import static com.google.common.base.Pre
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.toArray;
import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Lists.reverse;
import static java.util.Collections.singletonList;
import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
import static org.apache.jackrabbit.oak.plugins.document.Collection.JOURNAL;
@@ -81,6 +83,7 @@ import org.apache.jackrabbit.oak.commons
import org.apache.jackrabbit.oak.plugins.blob.BlobStoreBlob;
import org.apache.jackrabbit.oak.plugins.blob.MarkSweepGarbageCollector;
import org.apache.jackrabbit.oak.plugins.blob.ReferencedBlob;
+import org.apache.jackrabbit.oak.plugins.document.Branch.BranchCommit;
import org.apache.jackrabbit.oak.plugins.document.cache.CacheInvalidationStats;
import
org.apache.jackrabbit.oak.plugins.document.persistentCache.PersistentCache;
import
org.apache.jackrabbit.oak.plugins.document.persistentCache.broadcast.DynamicBroadcastConfig;
@@ -1249,8 +1252,7 @@ public final class DocumentNodeStore
@Nonnull
RevisionVector reset(@Nonnull RevisionVector branchHead,
- @Nonnull RevisionVector ancestor,
- @Nullable DocumentNodeStoreBranch branch) {
+ @Nonnull RevisionVector ancestor) {
checkNotNull(branchHead);
checkNotNull(ancestor);
Branch b = getBranches().getBranch(branchHead);
@@ -1261,61 +1263,44 @@ public final class DocumentNodeStore
throw new DocumentStoreException(branchHead + " is not the head " +
"of a branch");
}
- if (!b.containsCommit(ancestor.getBranchRevision())) {
+ if (!b.containsCommit(ancestor.getBranchRevision())
+ &&
!b.getBase().asBranchRevision(getClusterId()).equals(ancestor)) {
throw new DocumentStoreException(ancestor + " is not " +
"an ancestor revision of " + branchHead);
}
- if (branchHead.equals(ancestor)) {
+ // tailSet is inclusive -> use an ancestorRev with a
+ // counter incremented by one to make the call exclusive
+ Revision ancestorRev = ancestor.getBranchRevision();
+ ancestorRev = new Revision(ancestorRev.getTimestamp(),
+ ancestorRev.getCounter() + 1, ancestorRev.getClusterId(),
true);
+ List<Revision> revs =
newArrayList(b.getCommits().tailSet(ancestorRev));
+ if (revs.isEmpty()) {
// trivial
return branchHead;
}
- boolean success = false;
- Commit commit = newCommit(branchHead, branch);
- try {
- Iterator<Revision> it =
b.getCommits().tailSet(ancestor.getBranchRevision()).iterator();
- // first revision is the ancestor (tailSet is inclusive)
- // do not undo changes for this revision
- it.next();
- Map<String, UpdateOp> operations = Maps.newHashMap();
- if (it.hasNext()) {
- Revision reset = it.next();
- // TODO: correct?
- getRoot(b.getCommit(reset).getBase().update(reset))
- .compareAgainstBaseState(getRoot(ancestor),
- new ResetDiff(reset.asTrunkRevision(),
operations));
- UpdateOp rootOp = operations.get("/");
- if (rootOp == null) {
- rootOp = new UpdateOp(Utils.getIdFromPath("/"), false);
- NodeDocument.setModified(rootOp, commit.getRevision());
- operations.put("/", rootOp);
- }
- NodeDocument.removeCollision(rootOp, reset.asTrunkRevision());
- NodeDocument.removeRevision(rootOp, reset.asTrunkRevision());
- }
- // update root document first
- if (store.findAndUpdate(Collection.NODES, operations.get("/")) !=
null) {
- // clean up in-memory branch data
- // first revision is the ancestor (tailSet is inclusive)
- List<Revision> revs =
Lists.newArrayList(b.getCommits().tailSet(ancestor.getBranchRevision()));
- for (Revision r : revs.subList(1, revs.size())) {
- b.removeCommit(r);
- }
- // successfully updating the root document can be considered
- // as success because the changes are not marked as committed
- // anymore
- success = true;
+ UpdateOp rootOp = new UpdateOp(Utils.getIdFromPath("/"), false);
+ // reset each branch commit in reverse order
+ Map<String, UpdateOp> operations = Maps.newHashMap();
+ for (Revision r : reverse(revs)) {
+ NodeDocument.removeCollision(rootOp, r.asTrunkRevision());
+ NodeDocument.removeRevision(rootOp, r.asTrunkRevision());
+ operations.clear();
+ BranchCommit bc = b.getCommit(r);
+ if (bc.isRebase()) {
+ continue;
}
- operations.remove("/");
- // update remaining documents
+ getRoot(bc.getBase().update(r))
+ .compareAgainstBaseState(getRoot(bc.getBase()),
+ new ResetDiff(r.asTrunkRevision(), operations));
+ // apply reset operations
for (UpdateOp op : operations.values()) {
store.findAndUpdate(Collection.NODES, op);
}
- } finally {
- if (!success) {
- canceled(commit);
- } else {
- done(commit, true, null);
- }
+ }
+ store.findAndUpdate(Collection.NODES, rootOp);
+ // clean up in-memory branch data
+ for (Revision r : revs) {
+ b.removeCommit(r);
}
return ancestor;
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java?rev=1725542&r1=1725541&r2=1725542&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
Tue Jan 19 15:02:57 2016
@@ -620,8 +620,7 @@ class DocumentNodeStoreBranch implements
try {
head = store.getRoot(
store.reset(branchHead.getRevision(),
- ancestor.getRevision(),
- DocumentNodeStoreBranch.this));
+ ancestor.getRevision()));
} catch (Exception e) {
CommitFailedException ex = new CommitFailedException(
OAK, 100, "Branch reset failed", e);
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ResetDiff.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ResetDiff.java?rev=1725542&r1=1725541&r2=1725542&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ResetDiff.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ResetDiff.java
Tue Jan 19 15:02:57 2016
@@ -74,6 +74,7 @@ class ResetDiff implements NodeStateDiff
@Override
public boolean childNodeAdded(String name, NodeState after) {
+ NodeDocument.removeCommitRoot(getUpdateOp(), revision);
String p = PathUtils.concat(path, name);
ResetDiff diff = new ResetDiff(revision, p, operations);
UpdateOp op = diff.getUpdateOp();
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentMKResetTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentMKResetTest.java?rev=1725542&r1=1725541&r2=1725542&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentMKResetTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentMKResetTest.java
Tue Jan 19 15:02:57 2016
@@ -18,7 +18,6 @@ package org.apache.jackrabbit.oak.plugin
import java.util.Map;
-import org.junit.Ignore;
import org.junit.Test;
import static org.apache.jackrabbit.oak.plugins.document.Collection.NODES;
@@ -131,7 +130,6 @@ public class DocumentMKResetTest extends
assertPropExists(rev, "/foo", "p2");
}
- @Ignore
@Test
public void resetToBaseOfBranch() {
addNodes(null, "/foo");
@@ -142,7 +140,6 @@ public class DocumentMKResetTest extends
assertNodesNotExist(null, "/foo/bar");
}
- @Ignore
@Test
public void resetRemovesCommitRootOnParent() {
DocumentStore store = mk.getDocumentStore();
@@ -167,7 +164,6 @@ public class DocumentMKResetTest extends
Revision.fromString(b1).asTrunkRevision()));
}
- @Ignore
@Test
public void resetMultipleCommits() {
DocumentStore store = mk.getDocumentStore();