Merge Algorithm

The above declarative description can also be expressed in pseudo-code as follows:

let ws' be the workspace against which the merge is done.
let bestEffort be the flag passed to merge.
let failedset be a set of UUIDs, initially empty.
let startnode be the node on which merge was called.
return the nodes with the UUIDs in failedset.

let n' be the corresponding node of n in ws'.
if no such n' doleave(n).
else if n is not versionable doupdate(n, n').
else if n' is not versionable doleave(n).
let v be base version of n.
let v' be base version of n'.
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').

dofail(n, v')
if bestEffort = false throw MergeException.
else add UUID of v' (if not already present) to the
jcr:mergeFailed property of n,
add UUID of n to failedset,

for each child node c of n domerge(c).

doupdate(n, n')
replace set of properties of n with those of n'.
let S be the set of child nodes of n.
let S' be the set of child nodes of n'.
judging by the name of the child node:
let C be the set of nodes in S and in S'
let D be the set of nodes in S but not in S'.
let D' be the set of nodes in S' but not in S.
remove from n all child nodes in D.
for each child node of n' in D' copy it (and its subtree) to n
as a new child node (if an incoming node has the same
UUID as a node already existing in this workspace,
the already existing node is removed).
for each child node m of n in C domerge(m).