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.

Reply via email to