Node incorrectly overridden when performing a merge
---------------------------------------------------
Key: JCR-1314
URL: https://issues.apache.org/jira/browse/JCR-1314
Project: Jackrabbit
Issue Type: Bug
Components: versioning
Affects Versions: 1.4, 1.5
Reporter: Bob Wieler
Priority: Critical
The implementation of the merge algorithm provided in the JCR specification is
incorrect and can result in nodes being overridden. This can be demonstrated by
the following simple steps:
1. Create a repository with a nt:file node containing whatever data (n')
2. Commit the changes to the node to create the initial version (v')
3. Copy the node to a new workspace
4. Edit the node in the second workspace (n)
5. Commit the changes to the second workspace to create the second version (v)
6. Merge the changes from the first workspace into the second workspace
According to the JCR specification (from 8.2.10.1):
if v' is a successor of v and n is not checked-in doupdate(n, n').
else if v is equal to or a predecessor of v' doleave(n).
else dofail(n, v').
In the above example, v' is a predecessor of v so the doupdate(n, n') is not
done. v and v' are also not equal and v is not a predecessor of v' so the
doleaven(n) is not done. Therefore the dofail(n, v') is what should be called.
The code in NodeImpl.java is not however doing what is expected. Line 3337 in
NodeImpl.java (subversion revision 611855) has the following:
} else if (v.isSame(vp) || v.isMoreRecent(vp)) {
// If V' is a predecessor (to any degree) of V or if V and V' are
// identical (i.e., are actually the same version), then the merge
// result for N is leave. This case can be thought of as the case
where
// N' is "older" or the "same age" as N and therefore N should be
left alone.
return null;
} else {
The doMergeTest method returns null (essentially a doleave(n) in the spec
algorithm) if v and v' are the same or v' is a predecessor to v - in other
words if v and v' are the same or v is a _successor_ to v' - which is exactly
the opposite to what the specification requires (if v is equal to or a
_predecessor_ of v'). The proper if statement would be to have:
} else if (v.isSame(vp) || vp.isMoreRecent(v)) {
Unfortunately, this was causing us to lose data when performing a merge. I have
updated our version of jackrabbit with the above change and merging now works
as expected.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.