On Mon, Jan 9, 2012 at 6:14 AM, Julian Foad <julianf...@btopenworld.com> wrote: > Merging would be simpler if the user didn't have to think about doing the > "keep-alive dance" after a reintegrate [1]. > > I'm trying to teach the sync merge to detect when a reintegrate has been > done, so that we could avoid the need for r45 in the following typical > sequence: > > | Rev Branch Commit > | A B > |-------------------- > | r10 X > | | \ > | r20 | X "New branch B, a copy of A." > | | | > | r30 | X "Modify B." > | | / | > | r40 X | "Reintegrate from B into A." > | | \ | > | r45* | X "Record-only merge to keep B alive." > | | | > | r50 X | "More work in A." > | | \ | > | r60 | X "Sync from A into B." > > A patch in progress is attached. It makes 'merge' detect when one of the > revision ranges to be merged would include changes that have > already been merged in the opposite direction. At present it stops the > merge, giving a friendly error message. > > I would like to make it skip the particular revision(s) and continue to merge > all the other revisions in the range, but first we need to get the detection > right.
Hi Julian, Let me first say that I am all for trying to make this work. The need to delete and recreate a branch or use --record-only to block it, after reintegrating is not very user-friendly. That said, I think you'll find this trickier than it looks at first glance... > Using the above example, if we don't do the r45 record-only merge, then > during the last sync merge (which will be committed in r60), the normal merge > tracking code first determines that the revision range to be merged is > r11-r50 [2]. Then the new code detects that this incoming change brings in > new mergeinfo about merges *from* the current target branch B. Therefore the > new code will stop and complain. > > That's all right for simple cases but it's not good enough. > > We can say for sure that when we reintegrated B to A (in A:40), that will > have added new mergeinfo on A describing merges from B. However, if change > A:40 had instead been a different merge into A, let's say from C, it is still > possible that merge might have brought along some new mergeinfo describing > merges from B, because of the way mergeinfo is propagated from branch to > branch. Therefore, if we find that change A:40 adds new mergeinfo about > merges from B, we cannot simply say that A:40 describes a reintegrate merge > from B. Absolutely! There's also the similar case where 'B' is reintegrated to 'A', additional edits are made to 'A', and then the whole thing is committed as r40. Now r40 represents both the reintegrate change and unrelated edits -- but of course the smallest unit mergetracking works with is a revision, so how does it classify r40? > We need to look more closely. That's what I'm currently working on. This runs up against issue #2897 'Reflective merges are faulty'. You seem to be acknowledging this with your comments in the patch itself: "Note that with all these improvements, the result might approach a more flexible merge system in which any reflected or cyclic changes are skipped, *BUT WOULD NOT COPE* (emphasis mine) with the case where a revision in the source branch contains a mixture of changes merged from the target branch and other changes." But if we can't cope with that case how can we do anything that's an improvement over what we do today (i.e. just merge r40)? We can't skip r40 based on mergeinfo alone because there might be other legitimate changes. If we merge r40 that means we determined that *some* of the changes in that revision are legitimate. Do we apply only the fractional part of r40 that is legitimate? In other words, this whole thing appears to be a non-starter unless we can fix issue #2897. Is that your intention? Paul > Comments? > > - Julian > > > [1] See the end of > <http://wiki.apache.org/subversion/KeepingReintegratedBranchAlive>. > [2] Assume HEAD is r50 at this time.