I added a Wiki page [1] summarising and amending this proposal.
Michael
[1]
http://wiki.apache.org/jackrabbit/Conflict%20handling%20through%20rebasing%20branches
On 17.1.13 17:15, Michael Dürig wrote:
Hi,
There are various places in Oak where conflicting updates to the content
tree can occur: committing changes against a non root revision, merging
changes from a branch into trunk and synchronisation of cluster nodes.
The Microkernel API currently doesn't specify a contract for merging
conflicting changes but leaves it mostly to the underlying
implementation. As discussed before [1] this is not satisfactory and I'd
like to tighten the contract.
As announced earlier, I spent some time implementing various approaches
for rebasing branches in Oak. Apart from the other problems this solves
and which have been discussed at length, this also lends itself nicely
for a central, clean and efficient way of handling conflicts (I briefly
mentioned this in [2] already).
The core idea is to try to resolve all conflicts in a branch through
rebasing it on top of the current trunk. After successfully rebasing a
branch, merging it to trunk is as simple as fast forwarding the head of
the trunk to the head of the branch.
Here are a naive sample implementations of the relevant methods in
pseudo code. Note how commit is implemented in terms of branch and
merge. I has not to be implemented that way but rather the observable
behaviour should be like this.
/* Rebase branch on top of the head of the trunk. Returns false if
a conflict occurs, true otherwise. */
boolean rebase(branch) {
// See https://github.com/mduerig/jackrabbit-oak/commits/OAK-536
// and https://github.com/mduerig/jackrabbit-oak/commits/OAK-536-2
// for two possible implementations
}
int merge(branch) {
while(true) {
if (!rebase(branch)) {
throw new MicroKernelException("merge conflict");
}
atomic {
if (branch.baseRevision == trunk.headRevision) {
trunk.headRevision = branch.headRevision
return trunk.headRevision;
}
}
}
}
int commit(baseRevision, jsop) {
branch = createBranchFrom(baseRevision)
branch.apply(jsop)
if (!rebase(branch)) {
throw new MicroKernelException("merge conflict");
}
return merge(branch)
}
Michael
[1] http://markmail.org/message/4xwfwbax3kpoysbp
[2] http://markmail.org/message/niam2xs2ora5rufi