atom feed8 messages in org.apache.jackrabbit.oak-devConflict handling through rebasing br...
FromSent OnAttachments
Michael DürigJan 17, 2013 9:15 am 
Jukka ZittingJan 17, 2013 11:35 pm 
Thomas MuellerJan 18, 2013 12:59 am 
Michael DürigJan 18, 2013 1:07 am 
Michael DürigJan 18, 2013 1:37 am 
Jukka ZittingJan 18, 2013 1:57 am 
Michael DürigJan 18, 2013 2:40 am 
Michael DürigJan 29, 2013 8:08 am 
Subject:Conflict handling through rebasing branches
From:Michael Dürig (
Date:Jan 17, 2013 9:15:28 am


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 // and // 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) }


[1] [2]